complete and check auth pages - error handler

This commit is contained in:
Alihaghighattalab
2024-08-26 17:59:20 +03:30
parent 5ec6ffdacc
commit 10a6a746ed
20 changed files with 137 additions and 56 deletions
+7 -1
View File
@@ -3,13 +3,19 @@ import { AwardNotComplete } from "./award-not-complete"
import { getAwardsList } from "../../services/api/awards"
import { AwardsResponse } from "../../types"
import { AwardSkeleton } from "./award-skeleton"
import { handleError } from "../../utility/error-handle"
import { useEffect } from "react"
export const Awards = () => {
const { data, isLoading } = useQuery({
const { data, isLoading, error } = useQuery({
queryKey: ["awards"],
queryFn: getAwardsList
})
useEffect(() => {
handleError(error)
}, [error])
if (isLoading) return <AwardSkeleton />
return (
<div className="flex flex-col gap-10">
+31 -4
View File
@@ -1,11 +1,11 @@
import { flexRender, getCoreRowModel, getPaginationRowModel, useReactTable } from "@tanstack/react-table"
import { ArrowDown2, ArrowLeft2, ArrowRight2, ArrowUp2, SearchNormal1 } from "iconsax-react"
import { FC, useEffect } from "react"
import { FC, useEffect, useState } from "react"
import { Input } from "./input"
import { ComboBox } from "./combo-box"
import { Loading } from "./loading"
import { useParamsStore } from "../../store/params"
import { tableRows } from "../../utility/table-rows"
import { useParamsStore } from "../../store/params"
type Props = {
columns: any
@@ -16,8 +16,17 @@ type Props = {
tableScore?: number
}
type ADSortType = {
key: string,
value: 1 | -1
}
export const Table: FC<Props> = ({ columns, data, tableStatus = false, tableScore = 0, isLoading = false, totalData = 0 }) => {
const { updateParams, params } = useParamsStore()
const [aDSort, setADSort] = useState<ADSortType>({
key: "",
value: 1
})
const { updateParams, params, clearParams } = useParamsStore()
const totalPages = Math.ceil(totalData / params?.rows)
const table = useReactTable({
data: data ? data : [],
@@ -37,6 +46,19 @@ export const Table: FC<Props> = ({ columns, data, tableStatus = false, tableScor
})
}
useEffect(() => {
const newParams: any = {
page: params?.page,
rows: params?.rows,
search: params?.search,
};
clearParams(newParams)
if (aDSort?.key?.length > 0) {
newParams[aDSort.key] = aDSort.value;
}
updateParams(newParams);
}, [aDSort])
useEffect(() => {
updateParams({
page: 1,
@@ -62,7 +84,12 @@ export const Table: FC<Props> = ({ columns, data, tableStatus = false, tableScor
{table.getHeaderGroups().map((headerGroup: any, index: number) => (
<tr key={index}>
{headerGroup.headers.map((header: any, index: number) => (
<th key={index}>
<th key={index} onClick={() => {
setADSort({
key: header.getContext()?.column?.id,
value: aDSort?.value === 1 ? -1 : 1
})
}}>
<div {...{ className: header.column.getCanSort() ? "text-secondary-text-color text-base font-normal flex flex-row items-center justify-center gap-1 px-4 py-2" : "", onClick: header.column.getToggleSortingHandler() }}>
{flexRender(header.column.columnDef.header, header.getContext())}
{{ asc: <ArrowDown2 color="#777577" className="size-4" />, desc: <ArrowUp2 color="#777577" className="size-4" /> }[header.column.getIsSorted() as string] ?? null}
@@ -9,6 +9,7 @@ import { useMutation } from "@tanstack/react-query"
import { sendOTPMutation } from "../../services/api/auth"
import toast from "react-hot-toast"
import { ButtonComponent } from "../common/button"
import { handleError } from "../../utility/error-handle"
export const ForgotPasswordForm = () => {
const navigate = useNavigate()
@@ -33,10 +34,7 @@ export const ForgotPasswordForm = () => {
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}`)
}
onError: (err: any) => handleError(err)
}
)
}
+3 -3
View File
@@ -9,6 +9,7 @@ import { useMutation } from "@tanstack/react-query"
import { loginMutation } from "../../services/api/auth"
import { ButtonComponent } from "../common/button"
import toast from "react-hot-toast"
import { handleError } from "../../utility/error-handle"
export const LoginForm = () => {
const navigate = useNavigate()
@@ -33,9 +34,8 @@ export const LoginForm = () => {
toast.success("با موفقیت وارد شدین")
navigate("/")
},
onError: () => {
toast.error("نام کاربری یا رمز عبور اشتباه است")
}
onError: (err: any) => handleError(err)
})
}
@@ -9,6 +9,7 @@ import { ButtonComponent } from "../common/button"
import { useMutation } from "@tanstack/react-query"
import { sendOTPMutation } from "../../services/api/auth"
import toast from "react-hot-toast"
import { handleError } from "../../utility/error-handle"
export const LoginWithCodeForm = () => {
const navigate = useNavigate()
@@ -28,10 +29,8 @@ export const LoginWithCodeForm = () => {
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}`)
}
onError: (err: any) => handleError(err)
}
)
}
+3 -3
View File
@@ -13,6 +13,7 @@ import { getCitiesList } from "../../services/api/cities"
import { registerMutation } from "../../services/api/auth"
import { ButtonComponent } from "../common/button"
import toast from "react-hot-toast"
import { handleError } from "../../utility/error-handle"
export const RegisterForm = () => {
const [provinceData, setProvinceData] = useState<ComboBoxItems[] | []>([])
@@ -46,9 +47,8 @@ export const RegisterForm = () => {
toast.success("با موفقیت ثبت نام شدید")
navigate("/auth/login")
},
onError: (error: any) => {
console.log("error =>", error)
}
onError: (err: any) => handleError(err)
})
}
useEffect(() => {
@@ -10,6 +10,7 @@ import { checkOTP, sendOTPMutation } from "../../services/api/auth";
import toast from "react-hot-toast";
import { useEffect, useState } from "react";
import { ButtonComponent } from "../common/button";
import { handleError } from "../../utility/error-handle";
export const ResetpasswordCodeForm = () => {
const navigate = useNavigate()
@@ -40,10 +41,8 @@ export const ResetpasswordCodeForm = () => {
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}`)
}
onError: (err: any) => handleError(err)
})
}
@@ -57,9 +56,7 @@ export const ResetpasswordCodeForm = () => {
setSeconds(30)
setIsTimeUp(false)
},
onError: (err: any) => {
console.log("err=>", err)
}
onError: (err: any) => handleError(err)
})
}
@@ -96,7 +93,7 @@ export const ResetpasswordCodeForm = () => {
<OTPInput
containerStyle="otp-container"
{...field}
numInputs={5}
numInputs={6}
renderInput={(props) => <input {...props} />}
inputStyle="otp-inputs"
/>
@@ -108,7 +105,7 @@ export const ResetpasswordCodeForm = () => {
<div className="flex flex-col gap-y-[27px] items-center">
<p className="font-normal text-secondary-text-color text-base">{seconds} ثانیه دیگر تا دریافت کد</p>
<ButtonComponent title="تایید" pending={isPending} type="submit" />
<ButtonComponent title="ارسال مجدد" type="button" theme="glass" className="w-fit h-fit p-0" disable={!isTimeUp} pending={sendOTPPending} onClick={handleSendOTPAgain} />
<ButtonComponent title="ارسال مجدد" type="button" theme="glass" className={`w-fit h-fit p-0 ${!isTimeUp && "text-secondary-text-color"}`} disable={!isTimeUp} pending={sendOTPPending} onClick={handleSendOTPAgain} />
</div>
</div>
</form>
+2 -1
View File
@@ -9,6 +9,7 @@ import { useMutation } from "@tanstack/react-query"
import { resetPasswordMutation } from "../../services/api/auth"
import { ButtonComponent } from "../common/button"
import toast from "react-hot-toast"
import { handleError } from "../../utility/error-handle"
export const ResetPasswordForm = () => {
@@ -36,7 +37,7 @@ export const ResetPasswordForm = () => {
toast.success("تغییر رمز عبور با موفقیت انجام شد")
navigate("/auth/login")
},
onError: (err: any) => console.log("err=>", err)
onError: (err: any) => handleError(err)
})
}
return (
+12 -11
View File
@@ -1,5 +1,5 @@
import OTPInput from "react-otp-input"
import { Link, useSearchParams } from "react-router-dom"
import { Link, useNavigate, useSearchParams } from "react-router-dom"
import { ErrorComponent } from "../common/error"
import { Controller, SubmitHandler, useForm } from "react-hook-form"
import { LoginWithOTP } from "../../types"
@@ -10,8 +10,10 @@ import { ButtonComponent } from "../common/button"
import { useMutation } from "@tanstack/react-query"
import { loginWithOTP, sendOTPMutation } from "../../services/api/auth"
import toast from "react-hot-toast"
import { handleError } from "../../utility/error-handle"
export const SendCodeForm = () => {
const navigate = useNavigate()
const { mutate, isPending } = useMutation({
mutationFn: sendOTPMutation,
mutationKey: ["send-otp"]
@@ -36,9 +38,8 @@ export const SendCodeForm = () => {
setSeconds(30)
setIsTimeUp(false)
},
onError: (err: any) => {
console.log("err=>", err)
}
onError: (err: any) => handleError(err)
})
}
const submitCode: SubmitHandler<LoginWithOTP> = async (data) => {
@@ -47,14 +48,14 @@ export const SendCodeForm = () => {
mobile_number: searchParams.get("phone_number"),
},
{
onSuccess: () => {
toast.success(`کد ورود برای شماره ${searchParams.get("phone_number")} ارسال شد`)
onSuccess: (res: any) => {
toast.success("با موفقیت وارد شدید")
window.localStorage.setItem("token", res?.data?.token)
navigate("/")
setSeconds(30)
setIsTimeUp(false)
},
onError: (err: any) => {
console.log("err=>", err)
}
onError: (err: any) => handleError(err)
})
}
useEffect(() => {
@@ -89,7 +90,7 @@ export const SendCodeForm = () => {
<OTPInput
containerStyle="otp-container"
{...field}
numInputs={5}
numInputs={6}
renderInput={(props) => <input {...props} />}
inputStyle="otp-inputs"
/>
@@ -101,7 +102,7 @@ export const SendCodeForm = () => {
<div className="flex flex-col gap-y-[27px] items-center">
{!isTimeUp && <p className="font-normal text-secondary-text-color text-base">{seconds} ثانیه دیگر تا دریافت کد</p>}
<ButtonComponent title="تایید" pending={loginOtpPending} type="submit" />
<ButtonComponent title="ارسال مجدد" type="button" theme="glass" className="w-fit h-fit p-0" disable={!isTimeUp} pending={isPending} onClick={handleSendOTPAgain} />
<ButtonComponent title="ارسال مجدد" type="button" theme="glass" className={`w-fit h-fit p-0 ${!isTimeUp && "text-secondary-text-color"}`} disable={!isTimeUp} pending={isPending} onClick={handleSendOTPAgain} />
</div>
</div>
</form>
+6 -1
View File
@@ -5,9 +5,10 @@ import { getOverviewDetails } from "../../services/api/overview"
import { useEffect, useState } from "react"
import { Coin1, DollarCircle, Radar, Star } from "iconsax-react"
import { HomeStatusSkeleton } from "./status-skeleton"
import { handleError } from "../../utility/error-handle"
export const StatusBox = () => {
const { data, isLoading } = useQuery({
const { data, isLoading, error } = useQuery({
queryKey: ['overview'],
queryFn: getOverviewDetails
})
@@ -40,6 +41,10 @@ export const StatusBox = () => {
}])
}, [data])
useEffect(() => {
handleError(error)
}, [error])
if (isLoading) return <HomeStatusSkeleton />
return (
<div className="grid grid-cols-1 sm:grid-cols-2 2xl:grid-cols-4 gap-6">
@@ -5,6 +5,7 @@ import { useMutation } from "@tanstack/react-query"
import { getRegisterDeviceList } from "../../services/api/register-device"
import { RegisterDeviceResponse } from "../../types"
import { useParamsStore } from "../../store/params"
import { handleError } from "../../utility/error-handle"
export const InstallationReports = () => {
const { params } = useParamsStore()
@@ -25,6 +26,9 @@ export const InstallationReports = () => {
data: res?.data?.data,
total: res?.data?.total
})
},
onError: (err: any) => {
handleError(err)
}
})
}, [mutate, params])
@@ -11,6 +11,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"
import { createNewCardMutation } from "../../services/api/bank-card"
import toast from "react-hot-toast"
import { ButtonComponent } from "../common/button"
import { handleError } from "../../utility/error-handle"
type Props = {
isOpen: boolean,
@@ -35,9 +36,7 @@ export const AddNewCardDialog: FC<Props> = ({ isOpen, close }) => {
queryClient.invalidateQueries({ queryKey: ["bank-card"] })
close()
},
onError: () => {
toast.error("کارت با موفقیت اضافه نشد")
}
onError: (err: any) => handleError(err)
})
}
useEffect(() => {
@@ -5,6 +5,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"
import { deleteCardMutation } from "../../services/api/bank-card"
import toast from "react-hot-toast"
import { ButtonComponent } from "../common/button"
import { handleError } from "../../utility/error-handle"
type Props = {
isOpen: boolean,
@@ -27,7 +28,7 @@ export const DeleteCardDialog: FC<Props> = ({ isOpen, close, id }) => {
queryClient.invalidateQueries({ queryKey: ["bank-card"] })
close()
},
onError: () => toast.error("حذف کارت نا موفق")
onError: (err: any) => handleError(err)
})
}
return (
@@ -1,4 +1,4 @@
import { useState } from "react"
import { useEffect, useState } from "react"
import { CardBank } from "../../types"
import { CreateNewCart } from "./create-new-cart"
import { AddNewCardDialog } from "./add-new-cart-dialog"
@@ -7,19 +7,25 @@ import { useQuery } from "@tanstack/react-query"
import { getUserCardsList } from "../../services/api/bank-card"
import { BankCart } from "./bank-cart"
import { ManagementBankCardSkeleton } from "./bank-card-skeleton"
import { handleError } from "../../utility/error-handle"
export const ManagementBankAccounts = () => {
const [selectedCard, setSelectedCard] = useState<string | number | null>(null)
const { data, isLoading } = useQuery({
const { data, isLoading, error } = useQuery({
queryKey: ["bank-card"],
queryFn: getUserCardsList
})
const [showDialog, setShowDialog] = useState<boolean>(false)
const handleCloseDialog = () => setShowDialog(false)
const handleOpenDialog = () => !isLoading && setShowDialog(true)
const [showDeleteDialog, setShowDeleteDialog] = useState<boolean>(false)
const handleOpenDeleteDialog = () => !isLoading && setShowDeleteDialog(true)
const handleCloseDeleteDialog = () => setShowDeleteDialog(false)
useEffect(() => {
handleError(error)
}, [error])
return (
<>
<div className="w-full grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-6">
+4 -1
View File
@@ -5,6 +5,7 @@ import { useMutation } from "@tanstack/react-query"
import { getScoresList } from "../../services/api/score"
import { useParamsStore } from "../../store/params"
import { ScoreResponse } from "../../types"
import { handleError } from "../../utility/error-handle"
export const Score = () => {
const { params } = useParamsStore()
@@ -27,7 +28,9 @@ export const Score = () => {
total: res?.data?.total,
score: res?.data?.score
})
}
},
onError: (err: any) => handleError(err)
})
}, [mutate, params])
return (
+4
View File
@@ -5,6 +5,7 @@ import { getTransactionsList } from "../../services/api/transactions"
import { useMutation } from "@tanstack/react-query"
import { TransactionsResponse } from "../../types"
import { useParamsStore } from "../../store/params"
import { handleError } from "../../utility/error-handle"
export const Transactions = () => {
const { params } = useParamsStore()
@@ -25,6 +26,9 @@ export const Transactions = () => {
data: res?.data?.data,
total: res?.data?.total
})
},
onError: (err: any) => {
handleError(err)
}
})
}, [mutate, params])
+6 -1
View File
@@ -5,10 +5,11 @@ import { getWalletDetails } from "../../services/api/wallet"
import { useEffect, useState } from "react"
import { StatusBoxItemInterface } from "../../types"
import { Coin1, DollarCircle } from "iconsax-react"
import { handleError } from "../../utility/error-handle"
export const WalletPage = () => {
const [statusData, setStatusData] = useState<StatusBoxItemInterface[] | []>([])
const { data, isLoading } = useQuery({
const { data, isLoading, error } = useQuery({
queryKey: ["wallet"],
queryFn: getWalletDetails
})
@@ -29,6 +30,10 @@ export const WalletPage = () => {
}])
}, [data])
useEffect(() => {
handleError(error)
}, [error])
return (
<div className="flex flex-col gap-y-[30px] w-full">
<StatusBoxWallet statusData={statusData} isLoading={isLoading} />
+6 -6
View File
@@ -41,9 +41,9 @@ export const ResetPasswordCodeSchema = yup.object({
.matches(/^[0-9]{11}$/, "شماره تماس نامعتبر"),
otp: yup.string()
.required("وارد کردن کد الزامی میباشد")
.min(5, "کد نمیتوند کمتر از 5 رقم باشد")
.max(5, "کد نمیتواند بیشتر از 5 رقم باشد")
.matches(/^[0-9]{5}$/, "کد نامعتبر"),
.min(6, "کد نمیتوند کمتر از 6 رقم باشد")
.max(6, "کد نمیتواند بیشتر از 6 رقم باشد")
.matches(/^[0-9]{6}$/, "کد نامعتبر"),
})
export const LoginCodeSchema = yup.object({
@@ -53,9 +53,9 @@ export const LoginCodeSchema = yup.object({
.matches(/^[0-9]{11}$/, "شماره تماس نامعتبر"),
otp: yup.string()
.required("وارد کردن کد الزامی میباشد")
.min(5, "کد نمیتوند کمتر از 5 رقم باشد")
.max(5, " کد نمیتواند بیشتر از 5 رقم باشد")
.matches(/^[0-9]{5}$/, "کد نامعتبر"),
.min(6, "کد نمیتوند کمتر از 6 رقم باشد")
.max(6, " کد نمیتواند بیشتر از 6 رقم باشد")
.matches(/^[0-9]{6}$/, "کد نامعتبر"),
})
export const RegisterSchema = yup.object({
+6
View File
@@ -4,6 +4,7 @@ import { TableParams } from '../types';
type ZustandState = {
params: TableParams;
updateParams: (newParams: Partial<TableParams>) => void;
clearParams: (newParams: TableParams) => void;
};
export const useParamsStore = create<ZustandState>((set) => ({
@@ -20,4 +21,9 @@ export const useParamsStore = create<ZustandState>((set) => ({
...newParams,
},
})),
clearParams: (defaultParams: TableParams) =>
set((state) => ({
...state,
params: defaultParams,
})),
}));
+19
View File
@@ -0,0 +1,19 @@
import toast from "react-hot-toast";
export const handleError = (err: any) => {
if (err) {
const errorStatus: number = err?.response?.status;
const keys = errorStatus === 422 ? Object.keys(err?.response?.data.validation) : [];
const handle401Error = () => {
window.localStorage.clear()
window.location.href = "/auth/login"
}
switch (errorStatus) {
case 422: return toast.error(err?.response?.data?.validation[keys[0]]?.msg);
case 401: return handle401Error()
case 500: return toast.error(err?.response?.data?.msg);
default:
return toast.error(err?.response?.data?.msg);
}
}
}