complete auth pages sunc with api - complete cities and province combo box in register page
This commit is contained in:
@@ -7,12 +7,14 @@ type Props = {
|
|||||||
type?: "reset" | "button" | "submit" | undefined,
|
type?: "reset" | "button" | "submit" | undefined,
|
||||||
pending?: boolean,
|
pending?: boolean,
|
||||||
theme?: "primary" | "secondary" | "glass" | "light",
|
theme?: "primary" | "secondary" | "glass" | "light",
|
||||||
onClick?: () => void
|
onClick?: () => void,
|
||||||
|
disable?: boolean,
|
||||||
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ButtonComponent: FC<Props> = ({ title, type = "button", pending = false, theme = "primary", onClick }) => {
|
export const ButtonComponent: FC<Props> = ({ title, type = "button", pending = false, theme = "primary", onClick, disable = false, className }) => {
|
||||||
return (
|
return (
|
||||||
<Button type={type} onClick={onClick} className={clsx("flex flex-row gap-3 items-center justify-center", {
|
<Button type={type} disabled={disable} onClick={onClick} className={clsx(`flex flex-row gap-3 items-center justify-center ${className}`, {
|
||||||
"bg-primary-color text-white": theme === "primary",
|
"bg-primary-color text-white": theme === "primary",
|
||||||
"bg-transparent text-primary-color": theme === "glass",
|
"bg-transparent text-primary-color": theme === "glass",
|
||||||
"bg-dark-blue text-white": theme === "secondary",
|
"bg-dark-blue text-white": theme === "secondary",
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export const ComboBox: FC<Props> = ({ field, placeholder, className, data = [],
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Combobox value={field && field.value} onChange={mode === "default" ? field && field.onChange : (e: ComboBoxItems) => {
|
<Combobox value={field && field.value} onChange={mode === "default" ? field && field.onChange : (e: ComboBoxItems) => {
|
||||||
console.log(e)
|
|
||||||
updateParams({
|
updateParams({
|
||||||
rows: e?.id
|
rows: e?.id
|
||||||
})
|
})
|
||||||
@@ -36,9 +35,6 @@ export const ComboBox: FC<Props> = ({ field, placeholder, className, data = [],
|
|||||||
className={`input-style min-w-full ${className}`}
|
className={`input-style min-w-full ${className}`}
|
||||||
displayValue={(person: any) => person?.name}
|
displayValue={(person: any) => person?.name}
|
||||||
onChange={(event) => setQuery(event.target.value)}
|
onChange={(event) => setQuery(event.target.value)}
|
||||||
ref={field && field.ref}
|
|
||||||
name={field && field.name}
|
|
||||||
onBlur={field && field.onBlur}
|
|
||||||
/>
|
/>
|
||||||
<ComboboxButton className="absolute top-0 min-w-full h-full bg-transparent">
|
<ComboboxButton className="absolute top-0 min-w-full h-full bg-transparent">
|
||||||
<ArrowDown2 className="size-5 absolute left-5 top-5 p-0 text-secondary-text-color/70" />
|
<ArrowDown2 className="size-5 absolute left-5 top-5 p-0 text-secondary-text-color/70" />
|
||||||
@@ -47,7 +43,7 @@ export const ComboBox: FC<Props> = ({ field, placeholder, className, data = [],
|
|||||||
{data?.length > 0 && <ComboboxOptions
|
{data?.length > 0 && <ComboboxOptions
|
||||||
anchor="bottom start"
|
anchor="bottom start"
|
||||||
transition
|
transition
|
||||||
className="bg-white shadow min-w-[220px] mt-2 rounded-xl p-2"
|
className="bg-white shadow min-w-[220px] !max-h-[300px] mt-2 rounded-xl p-2"
|
||||||
>
|
>
|
||||||
{filteredValue.map((value) => (
|
{filteredValue.map((value) => (
|
||||||
<ComboboxOption
|
<ComboboxOption
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
import { Link } from "react-router-dom"
|
import { Link, useNavigate } from "react-router-dom"
|
||||||
import { Input } from "../common/input"
|
import { Input } from "../common/input"
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { ForgotPasswordInterface } from "../../types"
|
import { ForgotPasswordInterface } from "../../types"
|
||||||
import { yupResolver } from "@hookform/resolvers/yup"
|
import { yupResolver } from "@hookform/resolvers/yup"
|
||||||
import { forgotPasswordSchema } from "../../schema"
|
import { forgotPasswordSchema } from "../../schema"
|
||||||
import { ErrorComponent } from "../common/error"
|
import { ErrorComponent } from "../common/error"
|
||||||
import { Button } from "@headlessui/react"
|
import { useMutation } from "@tanstack/react-query"
|
||||||
|
import { sendOTPMutation } from "../../services/api/auth"
|
||||||
|
import toast from "react-hot-toast"
|
||||||
|
import { ButtonComponent } from "../common/button"
|
||||||
|
|
||||||
export const ForgotPasswordForm = () => {
|
export const ForgotPasswordForm = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: sendOTPMutation,
|
||||||
|
mutationKey: ["send-otp"]
|
||||||
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
@@ -15,7 +24,22 @@ export const ForgotPasswordForm = () => {
|
|||||||
} = useForm<ForgotPasswordInterface>({
|
} = useForm<ForgotPasswordInterface>({
|
||||||
resolver: yupResolver(forgotPasswordSchema)
|
resolver: yupResolver(forgotPasswordSchema)
|
||||||
})
|
})
|
||||||
const handleForgotSubmit: SubmitHandler<ForgotPasswordInterface> = async (data) => { console.log("data=>", data) }
|
const handleForgotSubmit: SubmitHandler<ForgotPasswordInterface> = async (data) => {
|
||||||
|
mutate({
|
||||||
|
...data
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(`کد ورود برای شماره ${data?.mobile_number} ارسال شد`)
|
||||||
|
navigate(`/auth/reset-password-code?phone_number=${data?.mobile_number}`)
|
||||||
|
},
|
||||||
|
onError: (err: any) => {
|
||||||
|
console.log("error", err)
|
||||||
|
navigate(`/auth/reset-password-code?phone_number=${data?.mobile_number}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(handleForgotSubmit)}
|
<form onSubmit={handleSubmit(handleForgotSubmit)}
|
||||||
@@ -29,15 +53,15 @@ export const ForgotPasswordForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-9 mb-[42px]">
|
<div className="mt-9 mb-[42px]">
|
||||||
<Controller control={control} name="phoneNumber" render={({ field }) => (
|
<Controller control={control} name="mobile_number" render={({ field }) => (
|
||||||
<div>
|
<div>
|
||||||
<Input type="number" placeholder="شماره موبایل" field={field} />
|
<Input type="number" placeholder="شماره موبایل" field={field} />
|
||||||
<ErrorComponent show={errors.phoneNumber} message={errors?.phoneNumber?.message} />
|
<ErrorComponent show={errors.mobile_number} message={errors?.mobile_number?.message} />
|
||||||
</div>
|
</div>
|
||||||
)} />
|
)} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-y-[27px] items-center">
|
<div className="flex flex-col gap-y-[27px] items-center">
|
||||||
<Button type="submit">دریافت کد تایید</Button>
|
<ButtonComponent title="دریافت کد تایید" type="submit" pending={isPending} />
|
||||||
<Link to="/auth/login">
|
<Link to="/auth/login">
|
||||||
<p className="font-medium text-base text-primary-color">بازگشت</p>
|
<p className="font-medium text-base text-primary-color">بازگشت</p>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,18 +1,39 @@
|
|||||||
import { Link } from "react-router-dom"
|
import { Link, useNavigate } from "react-router-dom"
|
||||||
import { Input } from "../common/input"
|
import { Input } from "../common/input"
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { LoginWithCodeInterface } from "../../types"
|
import { LoginWithCodeInterface } from "../../types"
|
||||||
import { yupResolver } from "@hookform/resolvers/yup"
|
import { yupResolver } from "@hookform/resolvers/yup"
|
||||||
import { LoginWithCodeSchema } from "../../schema"
|
import { LoginWithCodeSchema } from "../../schema"
|
||||||
import { ErrorComponent } from "../common/error"
|
import { ErrorComponent } from "../common/error"
|
||||||
import { Button } from "@headlessui/react"
|
import { ButtonComponent } from "../common/button"
|
||||||
|
import { useMutation } from "@tanstack/react-query"
|
||||||
|
import { sendOTPMutation } from "../../services/api/auth"
|
||||||
|
import toast from "react-hot-toast"
|
||||||
|
|
||||||
export const LoginWithCodeForm = () => {
|
export const LoginWithCodeForm = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: sendOTPMutation,
|
||||||
|
mutationKey: ["send-otp"]
|
||||||
|
})
|
||||||
const { handleSubmit, formState: { errors }, control } = useForm<LoginWithCodeInterface>({
|
const { handleSubmit, formState: { errors }, control } = useForm<LoginWithCodeInterface>({
|
||||||
resolver: yupResolver(LoginWithCodeSchema)
|
resolver: yupResolver(LoginWithCodeSchema)
|
||||||
})
|
})
|
||||||
const handleLoginWithCode: SubmitHandler<LoginWithCodeInterface> = async (data) => {
|
const handleLoginWithCode: SubmitHandler<LoginWithCodeInterface> = async (data) => {
|
||||||
console.log("data=>", data)
|
mutate({
|
||||||
|
...data
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(`کد ورود برای شماره ${data?.mobile_number} ارسال شد`)
|
||||||
|
navigate(`/auth/send-code?phone_number=${data?.mobile_number}`)
|
||||||
|
},
|
||||||
|
onError: (err: any) => {
|
||||||
|
console.log("error", err)
|
||||||
|
navigate(`/auth/send-code?phone_number=${data?.mobile_number}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(handleLoginWithCode)}
|
<form onSubmit={handleSubmit(handleLoginWithCode)}
|
||||||
@@ -26,15 +47,15 @@ export const LoginWithCodeForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-9 mb-[42px]">
|
<div className="mt-9 mb-[42px]">
|
||||||
<Controller control={control} name="phoneNumber" render={({ field }) => (
|
<Controller control={control} name="mobile_number" render={({ field }) => (
|
||||||
<div>
|
<div>
|
||||||
<Input type="number" placeholder="شماره موبایل" field={field} />
|
<Input type="number" placeholder="شماره موبایل" field={field} />
|
||||||
<ErrorComponent show={errors.phoneNumber} message={errors.phoneNumber?.message} />
|
<ErrorComponent show={errors.mobile_number} message={errors.mobile_number?.message} />
|
||||||
</div>
|
</div>
|
||||||
)} />
|
)} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-y-[27px] items-center">
|
<div className="flex flex-col gap-y-[27px] items-center">
|
||||||
<Button type="submit">دریافت کد تایید</Button>
|
<ButtonComponent title="دریافت کد تایید" pending={isPending} type="submit" />
|
||||||
<Link to="/auth/login">
|
<Link to="/auth/login">
|
||||||
<p className="font-medium text-base text-primary-color">بازگشت</p>
|
<p className="font-medium text-base text-primary-color">بازگشت</p>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,20 +1,75 @@
|
|||||||
import { Link } from "react-router-dom"
|
import { Link, useNavigate } from "react-router-dom"
|
||||||
import { ComboBox } from "../common/combo-box"
|
import { ComboBox } from "../common/combo-box"
|
||||||
import { Input } from "../common/input"
|
import { Input } from "../common/input"
|
||||||
import { Button } from "@headlessui/react"
|
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { RegisterInterface } from "../../types"
|
import { CitiesType, ComboBoxItems, ProvinceType, RegisterInterface } from "../../types"
|
||||||
import { yupResolver } from "@hookform/resolvers/yup"
|
import { yupResolver } from "@hookform/resolvers/yup"
|
||||||
import { RegisterSchema } from "../../schema"
|
import { RegisterSchema } from "../../schema"
|
||||||
import { ErrorComponent } from "../common/error"
|
import { ErrorComponent } from "../common/error"
|
||||||
|
import { getProvincesList } from "../../services/api/province"
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query"
|
||||||
|
import { useEffect, useState } from "react"
|
||||||
|
import { getCitiesList } from "../../services/api/cities"
|
||||||
|
import { registerMutation } from "../../services/api/auth"
|
||||||
|
import { ButtonComponent } from "../common/button"
|
||||||
|
import toast from "react-hot-toast"
|
||||||
|
|
||||||
export const RegisterForm = () => {
|
export const RegisterForm = () => {
|
||||||
const { handleSubmit, formState: { errors }, control } = useForm<RegisterInterface>({
|
const [provinceData, setProvinceData] = useState<ComboBoxItems[] | []>([])
|
||||||
|
const [citiesData, setCitiesData] = useState<ComboBoxItems[] | []>([])
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: registerMutation,
|
||||||
|
mutationKey: ["register"]
|
||||||
|
})
|
||||||
|
const { data: provinces } = useQuery({
|
||||||
|
queryFn: getProvincesList,
|
||||||
|
queryKey: ["province"]
|
||||||
|
})
|
||||||
|
const { data: cities } = useQuery({
|
||||||
|
queryFn: getCitiesList,
|
||||||
|
queryKey: ["cities"]
|
||||||
|
})
|
||||||
|
|
||||||
|
const { handleSubmit, formState: { errors }, control, watch } = useForm<RegisterInterface>({
|
||||||
resolver: yupResolver(RegisterSchema)
|
resolver: yupResolver(RegisterSchema)
|
||||||
})
|
})
|
||||||
|
const provinceName: any = watch("province_name");
|
||||||
const handleRegister: SubmitHandler<RegisterInterface> = async (data) => {
|
const handleRegister: SubmitHandler<RegisterInterface> = async (data) => {
|
||||||
console.log("data=>", data)
|
mutate({
|
||||||
|
...data,
|
||||||
|
province_name: data?.province_name?.name,
|
||||||
|
city_name: data?.province_name?.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success("با موفقیت ثبت نام شدید")
|
||||||
|
navigate("/auth/login")
|
||||||
|
},
|
||||||
|
onError: (error: any) => {
|
||||||
|
console.log("error =>", error)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
const tempArray: ComboBoxItems[] = [...provinceData]
|
||||||
|
provinces?.data?.data?.map((province: ProvinceType) => tempArray.push({
|
||||||
|
id: province?.ProvinceID,
|
||||||
|
name: province?.ProvinceName
|
||||||
|
}))
|
||||||
|
setProvinceData(tempArray)
|
||||||
|
}, [provinces])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const tempCities: any = []
|
||||||
|
const newCities = cities?.data?.data?.filter((city: CitiesType) => city?.ProvinceName.toLocaleLowerCase().includes(provinceName?.name.toLowerCase()))
|
||||||
|
newCities?.map((city: CitiesType) => tempCities?.push({
|
||||||
|
id: city?.CityID,
|
||||||
|
name: city?.CityName
|
||||||
|
}))
|
||||||
|
setCitiesData(tempCities)
|
||||||
|
}, [provinceName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(handleRegister)}
|
<form onSubmit={handleSubmit(handleRegister)}
|
||||||
className="w-full sm:w-fit sm:min-w-[500px] max-h-screen overflow-y-auto xl:w-1/2 xl:p-0 xl:py-5 p-10 flex flex-col bg-auth-form items-center gap-y-[42px] rounded-3x rounded-3xl">
|
className="w-full sm:w-fit sm:min-w-[500px] max-h-screen overflow-y-auto xl:w-1/2 xl:p-0 xl:py-5 p-10 flex flex-col bg-auth-form items-center gap-y-[42px] rounded-3x rounded-3xl">
|
||||||
@@ -31,43 +86,47 @@ export const RegisterForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 gap-y-5 mb-[42px] mt-9">
|
<div className="grid grid-cols-1 gap-y-5 mb-[42px] mt-9">
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-x-4 gap-y-5">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-x-4 gap-y-5">
|
||||||
<Controller control={control} name="name" render={({ field }) => <div>
|
<Controller control={control} name="first_name" render={({ field }) => <div>
|
||||||
<Input type="text" placeholder="نام" field={field} />
|
<Input type="text" placeholder="نام" field={field} />
|
||||||
<ErrorComponent show={errors.name} message={errors.name?.message} />
|
<ErrorComponent show={errors.first_name} message={errors.first_name?.message} />
|
||||||
</div>} />
|
</div>} />
|
||||||
<Controller control={control} name="family" render={({ field }) => <div>
|
<Controller control={control} name="last_name" render={({ field }) => <div>
|
||||||
<Input type="text" placeholder="نام خانوادگی" field={field} />
|
<Input type="text" placeholder="نام خانوادگی" field={field} />
|
||||||
<ErrorComponent show={errors.family} message={errors.family?.message} />
|
<ErrorComponent show={errors.last_name} message={errors.last_name?.message} />
|
||||||
</div>} />
|
</div>} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col lg:flex-row gap-y-5 gap-x-4">
|
<Controller control={control} name="national_code" render={({ field }) => (<div>
|
||||||
<Controller control={control} name="capCity" render={({ field }) => <div>
|
<Input type="text" placeholder="کد ملی" field={field} />
|
||||||
<ComboBox field={field} />
|
<ErrorComponent show={errors.national_code} message={errors.national_code?.message} />
|
||||||
<ErrorComponent show={errors.capCity} message={errors.capCity?.message} />
|
|
||||||
</div>} />
|
|
||||||
<Controller control={control} name="city" render={({ field }) => <div>
|
|
||||||
<ComboBox field={field} />
|
|
||||||
<ErrorComponent show={errors.city} message={errors.city?.message} />
|
|
||||||
</div>} />
|
|
||||||
</div>
|
|
||||||
<Controller control={control} name="marketName" render={({ field }) => (<div>
|
|
||||||
<Input type="text" placeholder="نام فروشگاه" field={field} />
|
|
||||||
<ErrorComponent show={errors.marketName} message={errors.marketName?.message} />
|
|
||||||
</div>)} />
|
</div>)} />
|
||||||
<Controller control={control} name="phoneNumber" render={({ field }) => <div>
|
<div className="flex flex-col lg:flex-row gap-y-5 gap-x-4">
|
||||||
|
<Controller control={control} name="province_name" render={({ field }) => <div>
|
||||||
|
<ComboBox field={field} data={provinceData} />
|
||||||
|
<ErrorComponent show={errors.province_name} message={errors.province_name?.message} />
|
||||||
|
</div>} />
|
||||||
|
<Controller control={control} name="city_name" render={({ field }) => <div>
|
||||||
|
<ComboBox field={field} data={citiesData} />
|
||||||
|
<ErrorComponent show={errors.city_name} message={errors.city_name?.message} />
|
||||||
|
</div>} />
|
||||||
|
</div>
|
||||||
|
<Controller control={control} name="shopName" render={({ field }) => (<div>
|
||||||
|
<Input type="text" placeholder="نام فروشگاه" field={field} />
|
||||||
|
<ErrorComponent show={errors.shopName} message={errors.shopName?.message} />
|
||||||
|
</div>)} />
|
||||||
|
<Controller control={control} name="mobile_number" render={({ field }) => <div>
|
||||||
<Input type="number" placeholder="شماره موبایل" field={field} />
|
<Input type="number" placeholder="شماره موبایل" field={field} />
|
||||||
<ErrorComponent show={errors.phoneNumber} message={errors.phoneNumber?.message} />
|
<ErrorComponent show={errors.mobile_number} message={errors.mobile_number?.message} />
|
||||||
</div>} />
|
</div>} />
|
||||||
<Controller control={control} name="password" render={({ field }) => <div>
|
<Controller control={control} name="password" render={({ field }) => <div>
|
||||||
<Input type="password" placeholder="رمز عبور" field={field} />
|
<Input type="password" placeholder="رمز عبور" field={field} />
|
||||||
<ErrorComponent show={errors.password} message={errors.password?.message} />
|
<ErrorComponent show={errors.password} message={errors.password?.message} />
|
||||||
</div>} />
|
</div>} />
|
||||||
<Controller control={control} name="repeatPassword" render={({ field }) => <div>
|
<Controller control={control} name="password_confirmation" render={({ field }) => <div>
|
||||||
<Input type="password" placeholder="تکرار رمز عبور" field={field} />
|
<Input type="password" placeholder="تکرار رمز عبور" field={field} />
|
||||||
<ErrorComponent show={errors.repeatPassword} message={errors.repeatPassword?.message} />
|
<ErrorComponent show={errors.password_confirmation} message={errors.password_confirmation?.message} />
|
||||||
</div>} />
|
</div>} />
|
||||||
</div>
|
</div>
|
||||||
<Button type="submit">ثبت نام</Button>
|
<ButtonComponent title="ثبت نام" pending={isPending} type="submit" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,19 +1,79 @@
|
|||||||
import { Button } from "@headlessui/react";
|
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
||||||
import OTPInput from "react-otp-input"
|
import OTPInput from "react-otp-input"
|
||||||
import { Link } from "react-router-dom"
|
import { Link, useNavigate, useSearchParams } from "react-router-dom"
|
||||||
import { ResetPasswordCodeInterface } from "../../types";
|
import { ResetPasswordCodeInterface } from "../../types";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import { ResetPasswordCodeSchema } from "../../schema";
|
import { ResetPasswordCodeSchema } from "../../schema";
|
||||||
import { ErrorComponent } from "../common/error";
|
import { ErrorComponent } from "../common/error";
|
||||||
|
import { useMutation } from "@tanstack/react-query";
|
||||||
|
import { checkOTP, sendOTPMutation } from "../../services/api/auth";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { ButtonComponent } from "../common/button";
|
||||||
|
|
||||||
export const ResetpasswordCodeForm = () => {
|
export const ResetpasswordCodeForm = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const [seconds, setSeconds] = useState(30);
|
||||||
|
const [isTimeUp, setIsTimeUp] = useState(false);
|
||||||
|
const [searchParams] = useSearchParams()
|
||||||
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: checkOTP,
|
||||||
|
mutationKey: ["check-otp"]
|
||||||
|
})
|
||||||
|
|
||||||
|
const { mutate: sendOTPMutate, isPending: sendOTPPending } = useMutation({
|
||||||
|
mutationFn: sendOTPMutation,
|
||||||
|
mutationKey: ["send-otp"]
|
||||||
|
})
|
||||||
|
|
||||||
const { handleSubmit, formState: { errors }, control } = useForm<ResetPasswordCodeInterface>({
|
const { handleSubmit, formState: { errors }, control } = useForm<ResetPasswordCodeInterface>({
|
||||||
resolver: yupResolver(ResetPasswordCodeSchema)
|
resolver: yupResolver(ResetPasswordCodeSchema)
|
||||||
})
|
})
|
||||||
|
|
||||||
const submitCode: SubmitHandler<ResetPasswordCodeInterface> = async (data) => {
|
const submitCode: SubmitHandler<ResetPasswordCodeInterface> = async (data) => {
|
||||||
console.log("data=>", data)
|
await mutate({
|
||||||
|
...data,
|
||||||
|
mobile_number: searchParams.get("phone_number"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(`کد وارد شده مطابقت دارد`)
|
||||||
|
navigate(`/auth/reset-password?mobile_number=${searchParams.get("phone_number")}&otp=${data?.otp}`)
|
||||||
|
},
|
||||||
|
onError: (err: any) => {
|
||||||
|
console.log("err=>", err)
|
||||||
|
navigate(`/auth/reset-password?mobile_number=${searchParams.get("phone_number")}&otp=${data?.otp}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSendOTPAgain = async () => {
|
||||||
|
await sendOTPMutate({
|
||||||
|
mobile_number: searchParams.get("phone_number")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(`کد ورود برای شماره ${searchParams.get("phone_number")} ارسال شد`)
|
||||||
|
setSeconds(30)
|
||||||
|
setIsTimeUp(false)
|
||||||
|
},
|
||||||
|
onError: (err: any) => {
|
||||||
|
console.log("err=>", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (seconds > 0) {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setSeconds(prevSeconds => prevSeconds - 1);
|
||||||
|
}, 1000);
|
||||||
|
return () => clearInterval(timer);
|
||||||
|
} else {
|
||||||
|
setIsTimeUp(true);
|
||||||
|
}
|
||||||
|
}, [seconds]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(submitCode)}
|
<form onSubmit={handleSubmit(submitCode)}
|
||||||
className="w-fit xl:w-1/2 xl:p-0 p-10 flex flex-col bg-auth-form justify-center items-center gap-y-[42px] rounded-3xl">
|
className="w-fit xl:w-1/2 xl:p-0 p-10 flex flex-col bg-auth-form justify-center items-center gap-y-[42px] rounded-3xl">
|
||||||
@@ -23,7 +83,7 @@ export const ResetpasswordCodeForm = () => {
|
|||||||
<span className="font-medium text-lg md:text-2xl xl:text-3xl text-primary-text-color">فراموشی رمز عبور</span>
|
<span className="font-medium text-lg md:text-2xl xl:text-3xl text-primary-text-color">فراموشی رمز عبور</span>
|
||||||
<div className="flex flex-row gap-x-0.5 items-center">
|
<div className="flex flex-row gap-x-0.5 items-center">
|
||||||
<div className="flex flex-col sm:flex-row gap-0.5 items-center">
|
<div className="flex flex-col sm:flex-row gap-0.5 items-center">
|
||||||
<p className="text-secondary-text-color font-normal text-xs md:text-sm">کد تایید ارسال شده به شماره 09376225448 را وارد کنید.</p>
|
<p className="text-secondary-text-color font-normal text-xs md:text-sm">کد تایید ارسال شده به شماره {searchParams.get("phone_number")} را وارد کنید.</p>
|
||||||
<Link to="/auth/forgot-password">
|
<Link to="/auth/forgot-password">
|
||||||
<p className="text-primary-color font-bold text-xs md:text-sm cursor-pointer">ویرایش</p>
|
<p className="text-primary-color font-bold text-xs md:text-sm cursor-pointer">ویرایش</p>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -31,7 +91,7 @@ export const ResetpasswordCodeForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-9 mb-[42px] flex w-full justify-center items-center" id="otp">
|
<div className="mt-9 mb-[42px] flex w-full justify-center items-center" id="otp">
|
||||||
<Controller control={control} name="code" render={({ field }) => (
|
<Controller control={control} name="otp" render={({ field }) => (
|
||||||
<div>
|
<div>
|
||||||
<OTPInput
|
<OTPInput
|
||||||
containerStyle="otp-container"
|
containerStyle="otp-container"
|
||||||
@@ -40,15 +100,15 @@ export const ResetpasswordCodeForm = () => {
|
|||||||
renderInput={(props) => <input {...props} />}
|
renderInput={(props) => <input {...props} />}
|
||||||
inputStyle="otp-inputs"
|
inputStyle="otp-inputs"
|
||||||
/>
|
/>
|
||||||
<ErrorComponent show={errors.code} message={errors.code?.message} />
|
<ErrorComponent show={errors.otp} message={errors.otp?.message} />
|
||||||
</div>
|
</div>
|
||||||
)} />
|
)} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-y-[27px] items-center">
|
<div className="flex flex-col gap-y-[27px] items-center">
|
||||||
<p className="font-normal text-secondary-text-color text-base">30 ثانیه دیگر تا دریافت کد</p>
|
<p className="font-normal text-secondary-text-color text-base">{seconds} ثانیه دیگر تا دریافت کد</p>
|
||||||
<Button type="submit">تایید</Button>
|
<ButtonComponent title="تایید" pending={isPending} type="submit" />
|
||||||
<p className="font-medium text-base text-primary-color">ارسال مجدد</p>
|
<ButtonComponent title="ارسال مجدد" type="button" theme="glass" className="w-fit h-fit p-0" disable={!isTimeUp} pending={sendOTPPending} onClick={handleSendOTPAgain} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
import { Link } from "react-router-dom"
|
import { Link, useNavigate, useSearchParams } from "react-router-dom"
|
||||||
import { Input } from "../common/input"
|
import { Input } from "../common/input"
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { ResetPasswordInterface } from "../../types"
|
import { ResetPasswordInterface } from "../../types"
|
||||||
import { yupResolver } from "@hookform/resolvers/yup"
|
import { yupResolver } from "@hookform/resolvers/yup"
|
||||||
import { resetPasswordSchema } from "../../schema"
|
import { resetPasswordSchema } from "../../schema"
|
||||||
import { Button } from "@headlessui/react"
|
|
||||||
import { ErrorComponent } from "../common/error"
|
import { ErrorComponent } from "../common/error"
|
||||||
|
import { useMutation } from "@tanstack/react-query"
|
||||||
|
import { resetPasswordMutation } from "../../services/api/auth"
|
||||||
|
import { ButtonComponent } from "../common/button"
|
||||||
|
import toast from "react-hot-toast"
|
||||||
|
|
||||||
|
|
||||||
export const ResetPasswordForm = () => {
|
export const ResetPasswordForm = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: resetPasswordMutation,
|
||||||
|
mutationKey: ["reset-password"]
|
||||||
|
})
|
||||||
|
const [searchParams] = useSearchParams()
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
@@ -17,7 +26,18 @@ export const ResetPasswordForm = () => {
|
|||||||
resolver: yupResolver(resetPasswordSchema)
|
resolver: yupResolver(resetPasswordSchema)
|
||||||
})
|
})
|
||||||
const handleResetPassword: SubmitHandler<ResetPasswordInterface> = async (data) => {
|
const handleResetPassword: SubmitHandler<ResetPasswordInterface> = async (data) => {
|
||||||
console.log("data=>", data)
|
await mutate({
|
||||||
|
...data,
|
||||||
|
mobile_number: searchParams.get("mobile_number"),
|
||||||
|
otp: searchParams.get("otp")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success("تغییر رمز عبور با موفقیت انجام شد")
|
||||||
|
navigate("/auth/login")
|
||||||
|
},
|
||||||
|
onError: (err: any) => console.log("err=>", err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(handleResetPassword)}
|
<form onSubmit={handleSubmit(handleResetPassword)}
|
||||||
@@ -27,7 +47,7 @@ export const ResetPasswordForm = () => {
|
|||||||
<div className="flex flex-col gap-y-5">
|
<div className="flex flex-col gap-y-5">
|
||||||
<span className="font-medium text-lg md:text-2xl xl:text-3xl text-primary-text-color">بازیابی رمز عبور</span>
|
<span className="font-medium text-lg md:text-2xl xl:text-3xl text-primary-text-color">بازیابی رمز عبور</span>
|
||||||
<div className="flex flex-col md:flex-row gap-0.5 items-center">
|
<div className="flex flex-col md:flex-row gap-0.5 items-center">
|
||||||
<p className="text-secondary-text-color font-normal text-xs md:text-sm">کد تایید ارسال شده به شماره 09376225448 را وارد کنید.</p>
|
<p className="text-secondary-text-color font-normal text-xs md:text-sm">کد تایید ارسال شده به شماره {searchParams.get("mobile_number")} را وارد کنید.</p>
|
||||||
<Link to="/auth/forgot-password">
|
<Link to="/auth/forgot-password">
|
||||||
<p className="text-primary-color font-bold text-xs md:text-sm cursor-pointer">ویرایش</p>
|
<p className="text-primary-color font-bold text-xs md:text-sm cursor-pointer">ویرایش</p>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -38,12 +58,12 @@ export const ResetPasswordForm = () => {
|
|||||||
<Input type="password" placeholder="رمز عبور" field={field} />
|
<Input type="password" placeholder="رمز عبور" field={field} />
|
||||||
<ErrorComponent show={errors.password} message={errors.password?.message} />
|
<ErrorComponent show={errors.password} message={errors.password?.message} />
|
||||||
</div>)} />
|
</div>)} />
|
||||||
<Controller control={control} name="repeatPassword" render={({ field }) => (<div>
|
<Controller control={control} name="password_confirmation" render={({ field }) => (<div>
|
||||||
<Input type="password" placeholder="تکرار رمز عبور" field={field} />
|
<Input type="password" placeholder="تکرار رمز عبور" field={field} />
|
||||||
<ErrorComponent show={errors.repeatPassword} message={errors.repeatPassword?.message} />
|
<ErrorComponent show={errors.password_confirmation} message={errors.password_confirmation?.message} />
|
||||||
</div>)} />
|
</div>)} />
|
||||||
</div>
|
</div>
|
||||||
<Button type="submit">ذخیره</Button>
|
<ButtonComponent title="ذخیره" pending={isPending} type="submit" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,19 +1,72 @@
|
|||||||
import OTPInput from "react-otp-input"
|
import OTPInput from "react-otp-input"
|
||||||
import { Link } from "react-router-dom"
|
import { Link, useSearchParams } from "react-router-dom"
|
||||||
import { ErrorComponent } from "../common/error"
|
import { ErrorComponent } from "../common/error"
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { Button } from "@headlessui/react"
|
import { LoginWithOTP } from "../../types"
|
||||||
import { LoginCodeInterface } from "../../types"
|
|
||||||
import { yupResolver } from "@hookform/resolvers/yup"
|
import { yupResolver } from "@hookform/resolvers/yup"
|
||||||
import { LoginCodeSchema } from "../../schema"
|
import { LoginCodeSchema } from "../../schema"
|
||||||
|
import { useEffect, useState } from "react"
|
||||||
|
import { ButtonComponent } from "../common/button"
|
||||||
|
import { useMutation } from "@tanstack/react-query"
|
||||||
|
import { loginWithOTP, sendOTPMutation } from "../../services/api/auth"
|
||||||
|
import toast from "react-hot-toast"
|
||||||
|
|
||||||
export const SendCodeForm = () => {
|
export const SendCodeForm = () => {
|
||||||
const { handleSubmit, formState: { errors }, control } = useForm<LoginCodeInterface>({
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: sendOTPMutation,
|
||||||
|
mutationKey: ["send-otp"]
|
||||||
|
})
|
||||||
|
const { mutate: loginOtpMutate, isPending: loginOtpPending } = useMutation({
|
||||||
|
mutationFn: loginWithOTP,
|
||||||
|
mutationKey: ["login-otp"]
|
||||||
|
})
|
||||||
|
const [seconds, setSeconds] = useState(30);
|
||||||
|
const [isTimeUp, setIsTimeUp] = useState(false);
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const { handleSubmit, formState: { errors }, control } = useForm<LoginWithOTP>({
|
||||||
resolver: yupResolver(LoginCodeSchema)
|
resolver: yupResolver(LoginCodeSchema)
|
||||||
})
|
})
|
||||||
const submitCode: SubmitHandler<LoginCodeInterface> = async (data) => {
|
const handleSendOTPAgain = async () => {
|
||||||
console.log("data=>", data)
|
await mutate({
|
||||||
|
mobile_number: searchParams.get("phone_number")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(`کد ورود برای شماره ${searchParams.get("phone_number")} ارسال شد`)
|
||||||
|
setSeconds(30)
|
||||||
|
setIsTimeUp(false)
|
||||||
|
},
|
||||||
|
onError: (err: any) => {
|
||||||
|
console.log("err=>", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
const submitCode: SubmitHandler<LoginWithOTP> = async (data) => {
|
||||||
|
loginOtpMutate({
|
||||||
|
...data,
|
||||||
|
mobile_number: searchParams.get("phone_number"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(`کد ورود برای شماره ${searchParams.get("phone_number")} ارسال شد`)
|
||||||
|
setSeconds(30)
|
||||||
|
setIsTimeUp(false)
|
||||||
|
},
|
||||||
|
onError: (err: any) => {
|
||||||
|
console.log("err=>", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
if (seconds > 0) {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setSeconds(prevSeconds => prevSeconds - 1);
|
||||||
|
}, 1000);
|
||||||
|
return () => clearInterval(timer);
|
||||||
|
} else {
|
||||||
|
setIsTimeUp(true);
|
||||||
|
}
|
||||||
|
}, [seconds]);
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(submitCode)}
|
<form onSubmit={handleSubmit(submitCode)}
|
||||||
className="w-fit xl:w-1/2 xl:p-0 p-10 flex flex-col bg-auth-form justify-center items-center gap-y-[42px] rounded-3xl">
|
className="w-fit xl:w-1/2 xl:p-0 p-10 flex flex-col bg-auth-form justify-center items-center gap-y-[42px] rounded-3xl">
|
||||||
@@ -23,7 +76,7 @@ export const SendCodeForm = () => {
|
|||||||
<span className="font-medium text-lg md:text-2xl xl:text-3xl text-primary-text-color">ورود با رمز یکبار مصرف</span>
|
<span className="font-medium text-lg md:text-2xl xl:text-3xl text-primary-text-color">ورود با رمز یکبار مصرف</span>
|
||||||
<div className="flex flex-row gap-x-0.5 items-center">
|
<div className="flex flex-row gap-x-0.5 items-center">
|
||||||
<div className="flex flex-col sm:flex-row gap-0.5 items-center">
|
<div className="flex flex-col sm:flex-row gap-0.5 items-center">
|
||||||
<p className="text-secondary-text-color font-normal text-xs md:text-sm">کد تایید ارسال شده به شماره 09376225448 را وارد کنید.</p>
|
<p className="text-secondary-text-color font-normal text-xs md:text-sm">کد تایید ارسال شده به شماره {searchParams.get("phone_number")} را وارد کنید.</p>
|
||||||
<Link to="/auth/login-with-code">
|
<Link to="/auth/login-with-code">
|
||||||
<p className="text-primary-color font-bold text-xs md:text-sm cursor-pointer">ویرایش</p>
|
<p className="text-primary-color font-bold text-xs md:text-sm cursor-pointer">ویرایش</p>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -31,7 +84,7 @@ export const SendCodeForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-9 mb-[42px] flex w-full justify-center items-center" id="otp">
|
<div className="mt-9 mb-[42px] flex w-full justify-center items-center" id="otp">
|
||||||
<Controller control={control} name="code" render={({ field }) => (
|
<Controller control={control} name="otp" render={({ field }) => (
|
||||||
<div>
|
<div>
|
||||||
<OTPInput
|
<OTPInput
|
||||||
containerStyle="otp-container"
|
containerStyle="otp-container"
|
||||||
@@ -40,15 +93,15 @@ export const SendCodeForm = () => {
|
|||||||
renderInput={(props) => <input {...props} />}
|
renderInput={(props) => <input {...props} />}
|
||||||
inputStyle="otp-inputs"
|
inputStyle="otp-inputs"
|
||||||
/>
|
/>
|
||||||
<ErrorComponent show={errors.code} message={errors.code?.message} />
|
<ErrorComponent show={errors.otp} message={errors.otp?.message} />
|
||||||
</div>
|
</div>
|
||||||
)} />
|
)} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-y-[27px] items-center">
|
<div className="flex flex-col gap-y-[27px] items-center">
|
||||||
<p className="font-normal text-secondary-text-color text-base">30 ثانیه دیگر تا دریافت کد</p>
|
{!isTimeUp && <p className="font-normal text-secondary-text-color text-base">{seconds} ثانیه دیگر تا دریافت کد</p>}
|
||||||
<Button type="submit">تایید</Button>
|
<ButtonComponent title="تایید" pending={loginOtpPending} type="submit" />
|
||||||
<p className="font-medium text-base text-primary-color">ارسال مجدد</p>
|
<ButtonComponent title="ارسال مجدد" type="button" theme="glass" className="w-fit h-fit p-0" disable={!isTimeUp} pending={isPending} onClick={handleSendOTPAgain} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
+7
-1
@@ -13,10 +13,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
font-family: 'vazirmatn', 'vaziren';
|
font-family: 'vazirmatn', 'vaziren';
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
|
scrollbar-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=number]::-webkit-outer-spin-button,
|
input[type=number]::-webkit-outer-spin-button,
|
||||||
@@ -38,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#otp {
|
#otp {
|
||||||
direction: ltr;
|
direction: ltr !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-12
@@ -13,13 +13,13 @@ export const loginSchema = yup.object({
|
|||||||
|
|
||||||
export const resetPasswordSchema = yup.object({
|
export const resetPasswordSchema = yup.object({
|
||||||
password: yup.string().min(8, "رمز عبور نمیتواند کمتر از 8 کاراکتر باشد").required("رمز عبور الزامی میباشد"),
|
password: yup.string().min(8, "رمز عبور نمیتواند کمتر از 8 کاراکتر باشد").required("رمز عبور الزامی میباشد"),
|
||||||
repeatPassword: yup.string()
|
password_confirmation: yup.string()
|
||||||
.oneOf([yup.ref('password')], "رمز عبور و تکرار آن باید یکسان باشند")
|
.oneOf([yup.ref('password')], "رمز عبور و تکرار آن باید یکسان باشند")
|
||||||
.required("تکرار رمز عبور الزامی میباشد"),
|
.required("تکرار رمز عبور الزامی میباشد"),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const forgotPasswordSchema = yup.object({
|
export const forgotPasswordSchema = yup.object({
|
||||||
phoneNumber: yup.string()
|
mobile_number: yup.string()
|
||||||
.required("وارد کردن شماره تماس الزامی میباشد")
|
.required("وارد کردن شماره تماس الزامی میباشد")
|
||||||
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
||||||
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
||||||
@@ -27,7 +27,7 @@ export const forgotPasswordSchema = yup.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const LoginWithCodeSchema = yup.object({
|
export const LoginWithCodeSchema = yup.object({
|
||||||
phoneNumber: yup.string()
|
mobile_number: yup.string()
|
||||||
.required("وارد کردن شماره تماس الزامی میباشد")
|
.required("وارد کردن شماره تماس الزامی میباشد")
|
||||||
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
||||||
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
||||||
@@ -35,7 +35,11 @@ export const LoginWithCodeSchema = yup.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const ResetPasswordCodeSchema = yup.object({
|
export const ResetPasswordCodeSchema = yup.object({
|
||||||
code: yup.string()
|
mobile_number: yup.string()
|
||||||
|
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
||||||
|
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
||||||
|
.matches(/^[0-9]{11}$/, "شماره تماس نامعتبر"),
|
||||||
|
otp: yup.string()
|
||||||
.required("وارد کردن کد الزامی میباشد")
|
.required("وارد کردن کد الزامی میباشد")
|
||||||
.min(5, "کد نمیتوند کمتر از 5 رقم باشد")
|
.min(5, "کد نمیتوند کمتر از 5 رقم باشد")
|
||||||
.max(5, "کد نمیتواند بیشتر از 5 رقم باشد")
|
.max(5, "کد نمیتواند بیشتر از 5 رقم باشد")
|
||||||
@@ -43,7 +47,11 @@ export const ResetPasswordCodeSchema = yup.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const LoginCodeSchema = yup.object({
|
export const LoginCodeSchema = yup.object({
|
||||||
code: yup.string()
|
mobile_number: yup.string()
|
||||||
|
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
||||||
|
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
||||||
|
.matches(/^[0-9]{11}$/, "شماره تماس نامعتبر"),
|
||||||
|
otp: yup.string()
|
||||||
.required("وارد کردن کد الزامی میباشد")
|
.required("وارد کردن کد الزامی میباشد")
|
||||||
.min(5, "کد نمیتوند کمتر از 5 رقم باشد")
|
.min(5, "کد نمیتوند کمتر از 5 رقم باشد")
|
||||||
.max(5, " کد نمیتواند بیشتر از 5 رقم باشد")
|
.max(5, " کد نمیتواند بیشتر از 5 رقم باشد")
|
||||||
@@ -51,18 +59,19 @@ export const LoginCodeSchema = yup.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const RegisterSchema = yup.object({
|
export const RegisterSchema = yup.object({
|
||||||
name: yup.string().required("وارد کردن نام الزامی میباشد").min(3, "نام نمیتواند کمتر از 3 کاراکتر باشد").max(20, "نام نمیتواند بیشتر از 20 کاراکتر باشد"),
|
first_name: yup.string().required("وارد کردن نام الزامی میباشد").min(3, "نام نمیتواند کمتر از 3 کاراکتر باشد").max(20, "نام نمیتواند بیشتر از 20 کاراکتر باشد"),
|
||||||
family: yup.string().required("وارد کردن نام خانوادگی الزامی میباشد").min(3, "نام خانوادگی نمیتواند کمتر از 3 کاراکتر باشد").max(25, "نام خانوادگی نمیتواند بیشتر از 25 کاراکتر باشد"),
|
last_name: yup.string().required("وارد کردن نام خانوادگی الزامی میباشد").min(3, "نام خانوادگی نمیتواند کمتر از 3 کاراکتر باشد").max(25, "نام خانوادگی نمیتواند بیشتر از 25 کاراکتر باشد"),
|
||||||
city: yup.object().required("وارد کردن شهر الزامی مباشد"),
|
national_code: yup.string().required("وارد کردن کد ملی الزامی میباشد").min(10, "کد ملی نمیتواند کمتر از 10 کاراکتر باشد").max(10, "کد ملی نمیتونه بیشتر از 10 کاراکتر باشه").matches(/^[0-9]{10}$/, "کد نامعتبر"),
|
||||||
capCity: yup.object().required("وارد کردن استان الزامی مباشد"),
|
city_name: yup.object().required("وارد کردن شهر الزامی مباشد"),
|
||||||
marketName: yup.string().required("وارد کردن نام فروشگاه الزامی میباشد").min(2, "نام فروشگاه نمیتواند کمتر از 3 کاراکتر باشد").max(30, "نام فروشگاه نمیتواند بیشتر از 30 کاراکتر باشد"),
|
province_name: yup.object().required("وارد کردن استان الزامی مباشد"),
|
||||||
phoneNumber: yup.string()
|
shopName: yup.string().required("وارد کردن نام فروشگاه الزامی میباشد").min(2, "نام فروشگاه نمیتواند کمتر از 3 کاراکتر باشد").max(30, "نام فروشگاه نمیتواند بیشتر از 30 کاراکتر باشد"),
|
||||||
|
mobile_number: yup.string()
|
||||||
.required("وارد کردن شماره تماس الزامی میباشد")
|
.required("وارد کردن شماره تماس الزامی میباشد")
|
||||||
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
.min(11, "شماره تماس نمیتوند کمتر از 11 رقم باشد")
|
||||||
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
.max(11, "شماره تماس نمیتواند بیشتر از 11 رقم باشد")
|
||||||
.matches(/^[0-9]{11}$/, "شماره تماس نامعتبر"),
|
.matches(/^[0-9]{11}$/, "شماره تماس نامعتبر"),
|
||||||
password: yup.string().min(8, "رمز عبور نمیتواند کمتر از 8 کاراکتر باشد").required("رمز عبور الزامی میباشد"),
|
password: yup.string().min(8, "رمز عبور نمیتواند کمتر از 8 کاراکتر باشد").required("رمز عبور الزامی میباشد"),
|
||||||
repeatPassword: yup.string()
|
password_confirmation: yup.string()
|
||||||
.oneOf([yup.ref('password')], "رمز عبور و تکرار آن باید یکسان باشند")
|
.oneOf([yup.ref('password')], "رمز عبور و تکرار آن باید یکسان باشند")
|
||||||
.required("تکرار رمز عبور الزامی میباشد"),
|
.required("تکرار رمز عبور الزامی میباشد"),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
import { LoginWithCodeInterface, LoginWithOTP, RegisterInterface, ResetPasswordInterface } from "../../types";
|
||||||
import axiosInstance from "../axios";
|
import axiosInstance from "../axios";
|
||||||
|
|
||||||
export const loginMutation = (payload: any) => axiosInstance.post<any>("/auth/gps/login/pass", payload)
|
export const loginMutation = (payload: any) => axiosInstance.post<any>("/auth/gps/login/pass", payload)
|
||||||
|
export const registerMutation = (payload: RegisterInterface) => axiosInstance.post<any>("/auth/gps/register", payload)
|
||||||
|
export const sendOTPMutation = (payload: LoginWithCodeInterface) => axiosInstance.post<any>("/auth/gps/otp/send", payload)
|
||||||
|
export const loginWithOTP = (payload: LoginWithOTP) => axiosInstance.post<any>("/auth/gps/login/otp", payload)
|
||||||
|
export const checkOTP = (payload: LoginWithOTP) => axiosInstance.post<any>("/auth/gps/otp/check", payload)
|
||||||
|
export const resetPasswordMutation = (payload: ResetPasswordInterface) => axiosInstance.post<any>("/auth/gps/otp/reset-pass", payload)
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { CitiesResponse } from "../../types";
|
||||||
|
import axiosInstance from "../axios";
|
||||||
|
|
||||||
|
export const getCitiesList = () => axiosInstance.post<CitiesResponse>("/cross/getRouteManager", {
|
||||||
|
url: "/api/GetCity",
|
||||||
|
db: "verity"
|
||||||
|
})
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { ProvinceResponse } from "../../types";
|
||||||
|
import axiosInstance from "../axios";
|
||||||
|
|
||||||
|
export const getProvincesList = () => axiosInstance.post<ProvinceResponse, ProvinceResponse>("/cross/getRouteManager", {
|
||||||
|
url: "/api/GetProvince",
|
||||||
|
db: "verity"
|
||||||
|
})
|
||||||
+45
-13
@@ -11,34 +11,39 @@ export interface LoginResponseInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ResetPasswordInterface {
|
export interface ResetPasswordInterface {
|
||||||
|
mobile_number?: string | any,
|
||||||
|
otp?: string | any,
|
||||||
password: string,
|
password: string,
|
||||||
repeatPassword: string
|
password_confirmation: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ForgotPasswordInterface {
|
export interface ForgotPasswordInterface {
|
||||||
phoneNumber: string
|
mobile_number: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LoginWithCodeInterface {
|
export interface LoginWithCodeInterface {
|
||||||
phoneNumber: string
|
mobile_number: string | any
|
||||||
}
|
}
|
||||||
export interface ResetPasswordCodeInterface {
|
export interface ResetPasswordCodeInterface {
|
||||||
code: string
|
mobile_number?: string | any
|
||||||
|
otp: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LoginCodeInterface {
|
export interface LoginCodeInterface {
|
||||||
code: string
|
mobile_number: any
|
||||||
|
otp: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RegisterInterface {
|
export interface RegisterInterface {
|
||||||
name: string,
|
first_name: string
|
||||||
family: string,
|
last_name: string
|
||||||
city: object,
|
national_code: string
|
||||||
capCity: object,
|
city_name: object | any
|
||||||
marketName: string,
|
province_name: object | any
|
||||||
phoneNumber: string,
|
shopName: string
|
||||||
password: string,
|
mobile_number: string
|
||||||
repeatPassword: string,
|
password: string
|
||||||
|
password_confirmation: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SidebarInterface {
|
export interface SidebarInterface {
|
||||||
@@ -280,4 +285,31 @@ export interface TableParams {
|
|||||||
page: number,
|
page: number,
|
||||||
rows: number,
|
rows: number,
|
||||||
search: string
|
search: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProvinceType = {
|
||||||
|
ProvinceID: number,
|
||||||
|
ProvinceName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProvinceResponse {
|
||||||
|
data: { data: ProvinceType[] | [], }
|
||||||
|
error: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginWithOTP {
|
||||||
|
mobile_number?: string | any
|
||||||
|
otp: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CitiesType = {
|
||||||
|
CityID: number,
|
||||||
|
CityName: string,
|
||||||
|
ProvinceID: string,
|
||||||
|
ProvinceName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CitiesResponse {
|
||||||
|
data: CitiesType[] | [],
|
||||||
|
error: string | null | any
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user