sync bank card api and complete it
This commit is contained in:
@@ -6,7 +6,8 @@ type Props = {
|
||||
title: string
|
||||
type?: "reset" | "button" | "submit" | undefined,
|
||||
pending?: boolean,
|
||||
theme?: "primary" | "secondary" | "glass" | "light"
|
||||
theme?: "primary" | "secondary" | "glass" | "light",
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
export const ButtonComponent: FC<Props> = ({ title, type = "button", pending = false, theme = "primary" }) => {
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { installationReportsCol } from "../../utility/reports"
|
||||
import { Table } from "../common/table"
|
||||
import { getReportsList } from "../../services/api/reports"
|
||||
import { useState } from "react"
|
||||
import { SortingState } from "@tanstack/react-table"
|
||||
|
||||
export const InstallationReports = () => {
|
||||
const [sorting, setSorting] = useState<SortingState>([])
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["installation-reports-list"],
|
||||
queryFn: getReportsList
|
||||
})
|
||||
// const { data, isLoading } = useQuery({
|
||||
// queryKey: ["installation-reports-list"],
|
||||
// queryFn: getReportsList
|
||||
// })
|
||||
|
||||
if (isLoading) return <p>LODING .....</p>
|
||||
// if (isLoading) return <p>LODING .....</p>
|
||||
return (
|
||||
<Table columns={installationReportsCol} data={data?.data} sorting={sorting} setSorting={setSorting} />
|
||||
<Table columns={installationReportsCol} data={[]} sorting={sorting} setSorting={setSorting} />
|
||||
)
|
||||
}
|
||||
@@ -2,34 +2,40 @@ import { CardAdd } from "iconsax-react"
|
||||
import { DialogComponent } from "../common/dialog"
|
||||
import { FC } from "react"
|
||||
import { Input } from "../common/input"
|
||||
import { Button } from "@headlessui/react"
|
||||
import { bankCarts, findBankByPAN } from "../../utility/cart"
|
||||
import { Controller, SubmitHandler, useForm } from "react-hook-form"
|
||||
import { AddNewCartInterface } from "../../types"
|
||||
import { yupResolver } from "@hookform/resolvers/yup"
|
||||
import { AddNewCardSchema } from "../../schema"
|
||||
import { ErrorComponent } from "../common/error"
|
||||
import { useMutation } from "@tanstack/react-query"
|
||||
import { createNewCardMutation } from "../../services/api/bank-card"
|
||||
import toast from "react-hot-toast"
|
||||
import { ButtonComponent } from "../common/button"
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean,
|
||||
close: () => void
|
||||
}
|
||||
export const AddNewCardDialog: FC<Props> = ({ isOpen, close }) => {
|
||||
const { mutate, isPending } = useMutation({
|
||||
mutationFn: createNewCardMutation
|
||||
})
|
||||
const { handleSubmit, formState: { errors }, control } = useForm<AddNewCartInterface>({
|
||||
resolver: yupResolver(AddNewCardSchema)
|
||||
})
|
||||
const createNewCard: SubmitHandler<AddNewCartInterface> = async (data) => {
|
||||
const finalData: any = {
|
||||
id: bankCarts?.length + 1,
|
||||
bankName: findBankByPAN(data.cartNumber).name,
|
||||
bankPersianName: findBankByPAN(data.cartNumber).name_farsi,
|
||||
cartNumber: data?.cartNumber.toString(),
|
||||
cartOwner: `${data.name} ${data?.family}`,
|
||||
shabaNumber: data?.shabaNumber,
|
||||
}
|
||||
console.log("final-data =>", finalData)
|
||||
bankCarts.push(finalData)
|
||||
close()
|
||||
mutate({
|
||||
holderName: `${data?.name} ${data?.family}`,
|
||||
PAN: data?.PAN,
|
||||
IBAN: data?.IBAN,
|
||||
}, {
|
||||
onSuccess: () => {
|
||||
toast.success("کارت با موفقیت اضافه شد")
|
||||
},
|
||||
onError: () => {
|
||||
toast.error("کارت با موفقیت اضافه نشد")
|
||||
}
|
||||
})
|
||||
}
|
||||
return (
|
||||
<DialogComponent isOpen={isOpen} close={close} title="ایجاد حساب بانکی جدید" subTitle="لطفا اطلاعات را با دقت وارد نمایید" icon={<CardAdd color="#11212D" className="size-[50px]" />}>
|
||||
@@ -47,22 +53,22 @@ export const AddNewCardDialog: FC<Props> = ({ isOpen, close }) => {
|
||||
<ErrorComponent show={errors.family} message={errors.family?.message} />
|
||||
</div>
|
||||
)} />
|
||||
<Controller control={control} name="cartNumber" render={({ field }) => (
|
||||
<Controller control={control} name="PAN" render={({ field }) => (
|
||||
<div>
|
||||
<Input field={field} placeholder="شماره کارت" className="bg-auth-form" />
|
||||
<ErrorComponent show={errors.cartNumber} message={errors.cartNumber?.message} />
|
||||
<ErrorComponent show={errors.PAN} message={errors.PAN?.message} />
|
||||
</div>
|
||||
)} />
|
||||
<Controller control={control} name="shabaNumber" render={({ field }) => (
|
||||
<Controller control={control} name="IBAN" render={({ field }) => (
|
||||
<div>
|
||||
<Input field={field} placeholder="شماره شبا" className="bg-auth-form" />
|
||||
<ErrorComponent show={errors.shabaNumber} message={errors.shabaNumber?.message} />
|
||||
<ErrorComponent show={errors.IBAN} message={errors.IBAN?.message} />
|
||||
</div>
|
||||
)} />
|
||||
</div>
|
||||
<div className="flex flex-col gap-[6px]">
|
||||
<Button type="submit" className="w-full bg-primary-color text-white">ایجاد حساب</Button>
|
||||
<Button onClick={close} className="w-full bg-transparent text-primary-color">لغو</Button>
|
||||
<ButtonComponent title="افزودن کارت" pending={isPending} type="submit" />
|
||||
<ButtonComponent title="لغو" pending={isPending} type="button" theme="glass" onClick={close} />
|
||||
</div>
|
||||
</form>
|
||||
</DialogComponent>
|
||||
|
||||
@@ -5,10 +5,11 @@ import { findBankByPAN, formatCartNumber } from "../../utility/cart"
|
||||
|
||||
type Props = {
|
||||
item: BankCartInterface,
|
||||
handleOpenDeleteDialog: () => void
|
||||
handleOpenDeleteDialog: () => void,
|
||||
setSelectedCard: (value: string | number | null) => void,
|
||||
}
|
||||
|
||||
export const BankCart: FC<Props> = ({ item, handleOpenDeleteDialog }) => {
|
||||
export const BankCart: FC<Props> = ({ item, handleOpenDeleteDialog, setSelectedCard }) => {
|
||||
return (
|
||||
<div className={`w-full flex flex-col justify-between rounded-[40px] bg-auth-form p-[18px] cursor-pointer bank-bg min-h-[226px]`} style={{ backgroundImage: `url('/svgs/banks/${item?.bankName}.svg')` }}>
|
||||
<div className="flex flex-row justify-between items-center">
|
||||
@@ -18,7 +19,7 @@ export const BankCart: FC<Props> = ({ item, handleOpenDeleteDialog }) => {
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<Trash color="#777577" onClick={handleOpenDeleteDialog} />
|
||||
<Edit color="#777577" />
|
||||
<Edit color="#777577" onClick={() => setSelectedCard(item?.id)} />
|
||||
</div>
|
||||
</div>
|
||||
<p className="font-medium text-2xl text-primary-text-color text-center" style={{ direction: "ltr" }}>{formatCartNumber(item?.cartNumber)}</p>
|
||||
|
||||
@@ -1,19 +1,34 @@
|
||||
import { FC } from "react"
|
||||
import { DialogComponent } from "../common/dialog"
|
||||
import { Trash } from "iconsax-react"
|
||||
import { Button } from "@headlessui/react"
|
||||
import { useMutation } from "@tanstack/react-query"
|
||||
import { deleteCardMutation } from "../../services/api/bank-card"
|
||||
import toast from "react-hot-toast"
|
||||
import { ButtonComponent } from "../common/button"
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean,
|
||||
close: () => void
|
||||
close: () => void,
|
||||
id: string | number | null
|
||||
}
|
||||
|
||||
export const DeleteCardDialog: FC<Props> = ({ isOpen, close }) => {
|
||||
export const DeleteCardDialog: FC<Props> = ({ isOpen, close, id }) => {
|
||||
const { mutate, isPending } = useMutation({
|
||||
mutationFn: deleteCardMutation
|
||||
})
|
||||
const handleDeleteSelectedCard = async () => {
|
||||
await mutate({
|
||||
id
|
||||
}, {
|
||||
onSuccess: () => toast.success("کارت مورد نظر با موفقیت حذف شد"),
|
||||
onError: () => toast.error("حذف کارت نا موفق")
|
||||
})
|
||||
}
|
||||
return (
|
||||
<DialogComponent isOpen={isOpen} close={close} title="حذف حساب بانکی" subTitle="از حذف حساب بانکی مربوطه اطمینان دارید؟" icon={<Trash color="#11212D" className="size-[50px]" />}>
|
||||
<div className="flex flex-col gap-[6px] mt-10">
|
||||
<Button className="w-full bg-primary-color text-white">حذف</Button>
|
||||
<Button onClick={close} className="w-full bg-transparent text-primary-color">لغو</Button>
|
||||
<ButtonComponent title="حذف" onClick={handleDeleteSelectedCard} pending={isPending} />
|
||||
<ButtonComponent title="لغو" onClick={close} theme="glass" />
|
||||
</div>
|
||||
</DialogComponent>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { BankCartInterface } from "../../types"
|
||||
import { bankCarts } from "../../utility/cart"
|
||||
import { BankCart } from "./bank-cart"
|
||||
import { CreateNewCart } from "./create-new-cart"
|
||||
import { AddNewCardDialog } from "./add-new-cart-dialog"
|
||||
@@ -9,6 +8,7 @@ import { useQuery } from "@tanstack/react-query"
|
||||
import { getUserCardsList } from "../../services/api/bank-card"
|
||||
|
||||
export const ManagementBankAccounts = () => {
|
||||
const [selectedCard, setSelectedCard] = useState<string | number | null>(null)
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["bank-card"],
|
||||
queryFn: getUserCardsList
|
||||
@@ -29,10 +29,10 @@ export const ManagementBankAccounts = () => {
|
||||
<>
|
||||
<div className="w-full grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-6">
|
||||
<CreateNewCart handleOpenDialog={handleOpenDialog} />
|
||||
{bankCarts?.map((item: BankCartInterface) => <BankCart key={item?.id} item={item} handleOpenDeleteDialog={handleOpenDeleteDialog} />)}
|
||||
{data?.data?.map((item: BankCartInterface) => <BankCart key={item?.id} item={item} handleOpenDeleteDialog={handleOpenDeleteDialog} setSelectedCard={setSelectedCard} />)}
|
||||
</div>
|
||||
<AddNewCardDialog isOpen={showDialog} close={handleCloseDialog} />
|
||||
<DeleteCardDialog isOpen={showDeleteDialog} close={handleCloseDeleteDialog} />
|
||||
<DeleteCardDialog isOpen={showDeleteDialog} close={handleCloseDeleteDialog} id={selectedCard} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -2,19 +2,17 @@ import { useState } from "react"
|
||||
import { Table } from "../common/table"
|
||||
import { SortingState } from "@tanstack/react-table"
|
||||
import { scoresCol } from "../../utility/score"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { getScoreList } from "../../services/api/score"
|
||||
|
||||
export const Score = () => {
|
||||
const [sorting, setSorting] = useState<SortingState>([])
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["score-list"],
|
||||
queryFn: getScoreList
|
||||
})
|
||||
// const { data, isLoading } = useQuery({
|
||||
// queryKey: ["score-list"],
|
||||
// queryFn: getScoreList
|
||||
// })
|
||||
|
||||
if (isLoading) return <p>LOADING ...</p>
|
||||
// if (isLoading) return <p>LOADING ...</p>
|
||||
|
||||
return (
|
||||
<Table sorting={sorting} setSorting={setSorting} columns={scoresCol} data={data?.data} tableStatus={true} />
|
||||
<Table sorting={sorting} setSorting={setSorting} columns={scoresCol} data={[]} tableStatus={true} />
|
||||
)
|
||||
}
|
||||
@@ -2,17 +2,15 @@ import { useState } from "react"
|
||||
import { Table } from "../common/table"
|
||||
import { SortingState } from "@tanstack/react-table"
|
||||
import { subscriptionsCol } from "../../utility/subscription"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { getSubscriptionsList } from "../../services/api/subscription"
|
||||
|
||||
export const SubscriptionReport = () => {
|
||||
const [sorting, setSorting] = useState<SortingState>([])
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["suscriptions-list"],
|
||||
queryFn: getSubscriptionsList
|
||||
})
|
||||
if (isLoading) return <p>LOADIN...</p>
|
||||
// const { data, isLoading } = useQuery({
|
||||
// queryKey: ["suscriptions-list"],
|
||||
// queryFn: getSubscriptionsList
|
||||
// })
|
||||
// if (isLoading) return <p>LOADIN...</p>
|
||||
return (
|
||||
<Table sorting={sorting} setSorting={setSorting} columns={subscriptionsCol} data={data?.data} />
|
||||
<Table sorting={sorting} setSorting={setSorting} columns={subscriptionsCol} data={[]} />
|
||||
)
|
||||
}
|
||||
@@ -2,19 +2,17 @@ import { useState } from "react"
|
||||
import { Table } from "../common/table"
|
||||
import { SortingState } from "@tanstack/react-table"
|
||||
import { transactionsCol } from "../../utility/transactions"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { getTransactionsList } from "../../services/api/transactions"
|
||||
|
||||
export const Transactions = () => {
|
||||
const [sorting, setSorting] = useState<SortingState>([])
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["transactions-list"],
|
||||
queryFn: getTransactionsList
|
||||
})
|
||||
// const { data, isLoading } = useQuery({
|
||||
// queryKey: ["transactions-list"],
|
||||
// queryFn: getTransactionsList
|
||||
// })
|
||||
|
||||
if (isLoading) return <p>LOADING ....</p>
|
||||
// if (isLoading) return <p>LOADING ....</p>
|
||||
return (
|
||||
<Table sorting={sorting} setSorting={setSorting} columns={transactionsCol} data={data?.data} />
|
||||
<Table sorting={sorting} setSorting={setSorting} columns={transactionsCol} data={[]} />
|
||||
)
|
||||
}
|
||||
+5
-5
@@ -100,14 +100,14 @@ export const MyAccountSchema = yup.object({
|
||||
export const AddNewCardSchema = yup.object({
|
||||
name: yup.string().required("وارد کردن نام الزامی میباشد").min(3, "نام نمیتواند کمتر از 3 کاراکتر باشد").max(20, "نام نمیتواند بیشتر از 20 کاراکتر باشد"),
|
||||
family: yup.string().required("وارد کردن نام خانوادگی الزامی میباشد").min(3, "نام خانوادگی نمیتواند کمتر از 3 کاراکتر باشد").max(25, "نام خانوادگی نمیتواند بیشتر از 25 کاراکتر باشد"),
|
||||
cartNumber: yup.string()
|
||||
PAN: yup.string()
|
||||
.required("وارد کردن شماره کارت الزامی میباشد")
|
||||
.min(16, "شماره کارت نمیتوند کمتر از 16 رقم باشد")
|
||||
.max(16, " شماره کارت نمیتواند بیشتر از 16 رقم باشد")
|
||||
.matches(/^[0-9]{16}$/, "شماره کارت نامعتبر"),
|
||||
shabaNumber: yup.string()
|
||||
IBAN: yup.string()
|
||||
.required("وارد کردن شماره شبا الزامی میباشد")
|
||||
.min(24, "شماره شبا نمیتوند کمتر از 24 رقم باشد")
|
||||
.max(24, " شماره شبا نمیتواند بیشتر از 24 رقم باشد")
|
||||
.matches(/^[0-9]{24}$/, "شماره شبا نامعتبر"),
|
||||
.min(26, "شماره شبا نمیتوند کمتر از 26 رقم باشد")
|
||||
.max(26, " شماره شبا نمیتواند بیشتر از 26 رقم باشد")
|
||||
.matches(/^IR[0-9]{24}$/, "شماره شبا نامعتبر"),
|
||||
})
|
||||
@@ -1,3 +1,3 @@
|
||||
import { axiosInstance } from "../axios";
|
||||
import axiosInstance from "../axios";
|
||||
|
||||
export const loginMutation = (payload: any) => axiosInstance.post<any>("/auth/gps/login", payload)
|
||||
@@ -1,4 +1,15 @@
|
||||
import { LoginFormInterface } from "../../types";
|
||||
import { axiosInstance } from "../axios";
|
||||
import axiosInstance from "../axios";
|
||||
|
||||
export const getUserCardsList = () => axiosInstance.get<LoginFormInterface>("/gps/bank-card")
|
||||
type CreateNewCard = {
|
||||
holderName: string,
|
||||
PAN: string,
|
||||
IBAN: string
|
||||
}
|
||||
|
||||
type DeleteCard = {
|
||||
id: string | number | null
|
||||
}
|
||||
|
||||
export const createNewCardMutation = (payload: CreateNewCard) => axiosInstance.post<any>("/gps/bank-card", payload)
|
||||
export const deleteCardMutation = (payload: DeleteCard) => axiosInstance.delete<any>(`/gps/bank-card/:${payload?.id}`)
|
||||
export const getUserCardsList = () => axiosInstance.get<any>("/gps/bank-card")
|
||||
@@ -1,4 +0,0 @@
|
||||
import { installationReportsInterface } from "../../types";
|
||||
import { axiosInstance } from "../axios";
|
||||
|
||||
export const getReportsList = () => axiosInstance.get<installationReportsInterface>("/reports")
|
||||
@@ -1,4 +0,0 @@
|
||||
import { ScoreInterface } from "../../types";
|
||||
import { axiosInstance } from "../axios";
|
||||
|
||||
export const getScoreList = () => axiosInstance.get<ScoreInterface>("/score")
|
||||
@@ -1,4 +0,0 @@
|
||||
import { SubscriptionReportInterface } from "../../types";
|
||||
import { axiosInstance } from "../axios";
|
||||
|
||||
export const getSubscriptionsList = () => axiosInstance.get<SubscriptionReportInterface>("/subscriptions")
|
||||
@@ -1,4 +0,0 @@
|
||||
import { TransactionsInterface } from "../../types";
|
||||
import { axiosInstance } from "../axios";
|
||||
|
||||
export const getTransactionsList = () => axiosInstance.get<TransactionsInterface>("/transactions")
|
||||
@@ -1,10 +0,0 @@
|
||||
import axios, { AxiosRequestConfig } from "axios";
|
||||
|
||||
const axiosParam: AxiosRequestConfig = {
|
||||
baseURL: "https://asan-service.com/api/",
|
||||
headers: {
|
||||
Authorization: `Bearer ${window.localStorage.getItem("token") && window.localStorage.getItem("token")}`,
|
||||
}
|
||||
}
|
||||
|
||||
export const axiosInstance = axios.create(axiosParam)
|
||||
@@ -0,0 +1,16 @@
|
||||
import axios from "axios";
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: process.env.REACT_APP_API_Address,
|
||||
});
|
||||
|
||||
axiosInstance.interceptors.request.use(async function (config) {
|
||||
const search = window.location.search;
|
||||
const params = new URLSearchParams(search)
|
||||
const token = localStorage.getItem("token") ? localStorage.getItem("token") : params.get('token')
|
||||
|
||||
config.headers.Authorization = 'Bearer ' + token
|
||||
return config;
|
||||
});
|
||||
|
||||
export default axiosInstance;
|
||||
@@ -0,0 +1,14 @@
|
||||
import { create } from "zustand";
|
||||
|
||||
type UserType = {
|
||||
token: string | null
|
||||
}
|
||||
|
||||
const useUserStore = create<UserType>((set) => ({
|
||||
token: '',
|
||||
setToken: (token: string | null) => {
|
||||
set({ token: token });
|
||||
},
|
||||
}));
|
||||
|
||||
export default useUserStore;
|
||||
+2
-2
@@ -101,8 +101,8 @@ export interface BanksInterface {
|
||||
export interface AddNewCartInterface {
|
||||
name: string
|
||||
family: string
|
||||
cartNumber: string
|
||||
shabaNumber: string
|
||||
PAN: string
|
||||
IBAN: string
|
||||
}
|
||||
|
||||
export interface installationReportsInterface {
|
||||
|
||||
Reference in New Issue
Block a user