From 1e8b54296077c35617193ae056b9fd17133f01e0 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Thu, 6 Feb 2025 11:22:25 +0330 Subject: [PATCH] bank crud --- .env | 2 +- src/config/Pages.ts | 5 + src/langs/fa.json | 15 +- src/pages/cardBank/Create.tsx | 159 ++++++++++++++++ src/pages/cardBank/Edit.tsx | 179 ++++++++++++++++++ src/pages/cardBank/List.tsx | 84 ++++++++ src/pages/cardBank/hooks/useCardBankData.ts | 46 +++++ src/pages/cardBank/service/CardBankService.ts | 22 +++ src/pages/cardBank/types/CardBankTypes.ts | 15 ++ src/router/Main.tsx | 6 + src/shared/SideBar.tsx | 8 + 11 files changed, 539 insertions(+), 2 deletions(-) create mode 100644 src/pages/cardBank/Create.tsx create mode 100644 src/pages/cardBank/Edit.tsx create mode 100644 src/pages/cardBank/List.tsx create mode 100644 src/pages/cardBank/hooks/useCardBankData.ts create mode 100644 src/pages/cardBank/service/CardBankService.ts create mode 100644 src/pages/cardBank/types/CardBankTypes.ts diff --git a/.env b/.env index 74f350e..baf030d 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ VITE_TOKEN_NAME = 'admin_token' VITE_REFRESH_TOKEN_NAME = 'admin_refresh_token' VITE_BASE_URL = 'https://danak-dsc-api.run.danakcorp.com' -# VITE_BASE_URL = 'http://192.168.0.207:3500' \ No newline at end of file +# VITE_BASE_URL = 'http://192.168.0.221:4000' \ No newline at end of file diff --git a/src/config/Pages.ts b/src/config/Pages.ts index 80fd7c5..c4bf670 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -77,4 +77,9 @@ export const Pages = { list: "/customers/list", create: "/customers/create", }, + cardBank: { + list: "/card-bank/list", + create: "/card-bank/create", + detail: "/card-bank/detail/", + }, }; diff --git a/src/langs/fa.json b/src/langs/fa.json index a79fa57..746e2eb 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -67,7 +67,8 @@ "criticisms": "انتقادات", "learning": "آموزش", "setting": "تنظیمات", - "logout": "خروج" + "logout": "خروج", + "card": "حساب های بانکی" }, "submenu": { "services_list": "لیست سرویس ها", @@ -556,5 +557,17 @@ "content": "برای حذف این آیتم مطمئن هستید؟", "yes": "بله", "cancel": "لغو" + }, + "cardBank": { + "new_account": "حساب جدید", + "submit_account": "ثبت حساب", + "account_information": "اطلاعات حساب", + "status_account": "وضعیت حساب", + "account_owner_name": "نام صاحب حساب", + "bank_name": "نام بانک", + "card_number": "شماره کارت", + "sheba": "شماره شبا", + "manage_banks": "مدیریت حساب های بانکی", + "add_account": "افزودن حساب" } } diff --git a/src/pages/cardBank/Create.tsx b/src/pages/cardBank/Create.tsx new file mode 100644 index 0000000..d53b62f --- /dev/null +++ b/src/pages/cardBank/Create.tsx @@ -0,0 +1,159 @@ +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import Button from '../../components/Button' +import { TickCircle, TickSquare } from 'iconsax-react' +import SwitchComponent from '../../components/Switch' +import Input from '../../components/Input' +import { useFormik } from 'formik' +import { CreateBankType } from './types/CardBankTypes' +import * as Yup from 'yup' +import { useCreateBank } from './hooks/useCardBankData' +import { useNavigate } from 'react-router-dom' +import { Pages } from '../../config/Pages' +import { ErrorType } from '../../helpers/types' +import { toast } from 'react-toastify' + +const CreateBankCard: FC = () => { + + const navigate = useNavigate() + const { t } = useTranslation('global') + const createBank = useCreateBank() + + const formik = useFormik({ + initialValues: { + accountOwnerName: '', + bankName: '', + cardNumber: '', + IBan: '', + isActive: true, + }, + validationSchema: Yup.object({ + accountOwnerName: Yup.string().required(t('errors.required')), + bankName: Yup.string().required(t('errors.required')), + cardNumber: Yup.string().required(t('errors.required')), + IBan: Yup.string().required(t('errors.required')), + }), + onSubmit: (values) => { + createBank.mutate(values, { + onSuccess: () => { + formik.resetForm() + navigate(Pages.cardBank.list) + }, + onError: (error: ErrorType) => { + toast.error(error.response?.data?.error?.message[0]) + } + }) + } + }) + + return ( +
+
+
+ {t('cardBank.new_account')} +
+
+ +
+
+ +
+
+
+ {t('cardBank.account_information')} +
+ +
+
+ {t('cardBank.status_account')} +
+ formik.setFieldValue('isActive', value)} + /> +
+ +
+ + +
+
+ + +
+
+ +
+
+ {t('ticket.title_hint')} +
+ +
+
+
+ +
+
+ سوالات - مشکلاتی که به یک موضوع مربوط میشوند را در یک درخواست پشتیبانی پیگیر باشید و چند درخواست برای یک موضوع باز نکنید. +
+
+
+
+ +
+
+ لطفاً برای بررسی و رفع مشکلات احتمالی صبور باشید بررسی و رفع مشکلات در برخی موارد زمان گیر است. +
+
+
+
+ +
+
+ پاسخگویی 24 ساعته تلفنی را تنها از میهن وب هاست می توانید انتظار داشته باشید .بخش پشتیبانی در هر ساعتی حتی در روز های تعطیل آماده پیگیری سریع مشکلات کاربران است. +
+
+
+
+
+
+ ) +} + +export default CreateBankCard \ No newline at end of file diff --git a/src/pages/cardBank/Edit.tsx b/src/pages/cardBank/Edit.tsx new file mode 100644 index 0000000..c374ab8 --- /dev/null +++ b/src/pages/cardBank/Edit.tsx @@ -0,0 +1,179 @@ +import { FC, useEffect } from 'react' +import { useTranslation } from 'react-i18next' +import Button from '../../components/Button' +import { TickCircle, TickSquare } from 'iconsax-react' +import SwitchComponent from '../../components/Switch' +import Input from '../../components/Input' +import { useFormik } from 'formik' +import { CreateBankType } from './types/CardBankTypes' +import * as Yup from 'yup' +import { useGetCardBankDetail, useUpdateBank } from './hooks/useCardBankData' +import { useNavigate, useParams } from 'react-router-dom' +import { Pages } from '../../config/Pages' +import { ErrorType } from '../../helpers/types' +import { toast } from 'react-toastify' + +const EditBankCard: FC = () => { + + const { id } = useParams() + const navigate = useNavigate() + const { t } = useTranslation('global') + const updateBank = useUpdateBank(id ? id : '') + const getCard = useGetCardBankDetail(id ? id : '') + + const formik = useFormik({ + initialValues: { + accountOwnerName: '', + bankName: '', + cardNumber: '', + IBan: '', + isActive: true, + }, + validationSchema: Yup.object({ + accountOwnerName: Yup.string().required(t('errors.required')), + bankName: Yup.string().required(t('errors.required')), + cardNumber: Yup.string().required(t('errors.required')), + IBan: Yup.string().required(t('errors.required')), + }), + onSubmit: (values) => { + updateBank.mutate(values, { + onSuccess: () => { + formik.resetForm() + navigate(Pages.cardBank.list) + }, + onError: (error: ErrorType) => { + toast.error(error.response?.data?.error?.message[0]) + } + }) + } + }) + + useEffect(() => { + + if (getCard.data?.data?.bankAccount) { + const data = getCard.data?.data?.bankAccount + + formik.setValues({ + accountOwnerName: data.accountOwnerName, + bankName: data.bankName, + cardNumber: data.cardNumber, + IBan: data.IBan, + isActive: data.isActive, + }) + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [getCard.data]) + + + return ( +
+
+
+ {t('cardBank.new_account')} +
+
+ +
+
+ +
+
+
+ {t('cardBank.account_information')} +
+ +
+
+ {t('cardBank.status_account')} +
+ formik.setFieldValue('isActive', value)} + /> +
+ +
+ + +
+
+ + +
+
+ +
+
+ {t('ticket.title_hint')} +
+ +
+
+
+ +
+
+ سوالات - مشکلاتی که به یک موضوع مربوط میشوند را در یک درخواست پشتیبانی پیگیر باشید و چند درخواست برای یک موضوع باز نکنید. +
+
+
+
+ +
+
+ لطفاً برای بررسی و رفع مشکلات احتمالی صبور باشید بررسی و رفع مشکلات در برخی موارد زمان گیر است. +
+
+
+
+ +
+
+ پاسخگویی 24 ساعته تلفنی را تنها از میهن وب هاست می توانید انتظار داشته باشید .بخش پشتیبانی در هر ساعتی حتی در روز های تعطیل آماده پیگیری سریع مشکلات کاربران است. +
+
+
+
+
+
+ ) +} + +export default EditBankCard \ No newline at end of file diff --git a/src/pages/cardBank/List.tsx b/src/pages/cardBank/List.tsx new file mode 100644 index 0000000..994812d --- /dev/null +++ b/src/pages/cardBank/List.tsx @@ -0,0 +1,84 @@ +import { FC } from 'react' +import { useGetCardBanks } from './hooks/useCardBankData' +import PageLoading from '../../components/PageLoading' +import Td from '../../components/Td' +import { useTranslation } from 'react-i18next' +import { CreateBankItemType } from './types/CardBankTypes' +import { Link } from 'react-router-dom' +import { Pages } from '../../config/Pages' +import Button from '../../components/Button' +import { Add, Eye } from 'iconsax-react' + +const CardBankList: FC = () => { + + const { t } = useTranslation('global') + const getCardBanks = useGetCardBanks() + + return ( +
+ +
+
+ + {t('cardBank.manage_banks')} +
+
+ + + +
+
+ { + getCardBanks.isPending ? + + : +
+ + + + + + + { + getCardBanks.data?.data?.bankAccounts?.map((item: CreateBankItemType) => { + return ( + + + + ) + }) + } + + +
+ + + + +
+ + + + + + + +
+ +
+ } +
+ ) +} + +export default CardBankList \ No newline at end of file diff --git a/src/pages/cardBank/hooks/useCardBankData.ts b/src/pages/cardBank/hooks/useCardBankData.ts new file mode 100644 index 0000000..8ad8a8b --- /dev/null +++ b/src/pages/cardBank/hooks/useCardBankData.ts @@ -0,0 +1,46 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { CreateBankType } from "../types/CardBankTypes"; +import * as api from "../service/CardBankService"; + +export const useCreateBank = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (variables: CreateBankType) => api.createCardBank(variables), + onSuccess: () => { + queryClient.refetchQueries({ + queryKey: ["cardBanks"], + }); + }, + }); +}; + +export const useGetCardBanks = () => { + return useQuery({ + queryKey: ["cardBanks"], + queryFn: api.getCardBanks, + }); +}; + +export const useGetCardBankDetail = (id: string) => { + return useQuery({ + queryKey: ["cardBank", id], + queryFn: () => api.getCardBankDetail(id), + enabled: !!id, + }); +}; + +export const useUpdateBank = (id: string) => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (variables: CreateBankType) => + api.updateCardBank(id, variables), + onSuccess: () => { + queryClient.refetchQueries({ + queryKey: ["cardBanks"], + }); + queryClient.refetchQueries({ + queryKey: ["cardBank", id], + }); + }, + }); +}; diff --git a/src/pages/cardBank/service/CardBankService.ts b/src/pages/cardBank/service/CardBankService.ts new file mode 100644 index 0000000..bea9319 --- /dev/null +++ b/src/pages/cardBank/service/CardBankService.ts @@ -0,0 +1,22 @@ +import axios from "../../../config/axios"; +import { CreateBankType } from "../types/CardBankTypes"; + +export const createCardBank = async (params: CreateBankType) => { + const { data } = await axios.post(`/payments/bank-account`, params); + return data; +}; + +export const getCardBanks = async () => { + const { data } = await axios.get(`/payments/bank-account`); + return data; +}; + +export const getCardBankDetail = async (id: string) => { + const { data } = await axios.get(`/payments/bank-account/${id}`); + return data; +}; + +export const updateCardBank = async (id: string, params: CreateBankType) => { + const { data } = await axios.patch(`/payments/bank-account/${id}`, params); + return data; +}; diff --git a/src/pages/cardBank/types/CardBankTypes.ts b/src/pages/cardBank/types/CardBankTypes.ts new file mode 100644 index 0000000..d482ffd --- /dev/null +++ b/src/pages/cardBank/types/CardBankTypes.ts @@ -0,0 +1,15 @@ +export type CreateBankType = { + cardNumber: string; + IBan: string; + bankName: string; + accountOwnerName: string; + isActive: boolean; +}; +export type CreateBankItemType = { + id: string; + cardNumber: string; + IBan: string; + bankName: string; + accountOwnerName: string; + isActive: boolean; +}; diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 4e9697b..5bd96bb 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -45,6 +45,9 @@ import CreateUser from '../pages/users/Create' import RolesList from '../pages/users/RolesList' import RoleCreate from '../pages/users/RoleCreate' import MessageDetail from '../pages/messages/Detail' +import CreateBankCard from '../pages/cardBank/Create' +import CardBankList from '../pages/cardBank/List' +import EditBankCard from '../pages/cardBank/Edit' const MainRouter: FC = () => { @@ -102,6 +105,9 @@ const MainRouter: FC = () => { } /> } /> } /> + } /> + } /> + } /> diff --git a/src/shared/SideBar.tsx b/src/shared/SideBar.tsx index 16f27e0..044f0c4 100644 --- a/src/shared/SideBar.tsx +++ b/src/shared/SideBar.tsx @@ -224,6 +224,14 @@ const SideBar: FC = () => {
+
+ } + title={t('sidebar.card')} + isActive={isActive('card')} + link={Pages.cardBank.list} + /> +
}