invoice pay approve , ...
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
import { FC, useState } from 'react'
|
||||||
|
import DefaulModal from './DefaulModal'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Button from './Button'
|
||||||
|
import Textarea from './Textarea'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isLoading?: boolean,
|
||||||
|
close: () => void,
|
||||||
|
isOpen: boolean,
|
||||||
|
onConfrim: (text?: string) => void,
|
||||||
|
label?: string,
|
||||||
|
isHasDescription?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModalConfrim: FC<Props> = (props: Props) => {
|
||||||
|
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
const [description, setDescription] = useState<string>('')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DefaulModal
|
||||||
|
open={props.isOpen}
|
||||||
|
close={props.close}
|
||||||
|
title_header={t('confrim.subject')}
|
||||||
|
isHeader
|
||||||
|
>
|
||||||
|
<div className='mt-6'>
|
||||||
|
<div className='text-sm text-center'>
|
||||||
|
{
|
||||||
|
props.label ?
|
||||||
|
props.label
|
||||||
|
:
|
||||||
|
t('confrim.content')
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
props.isHasDescription &&
|
||||||
|
<div className='mt-4'>
|
||||||
|
<Textarea
|
||||||
|
placeholder={t('description')}
|
||||||
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
|
value={description}
|
||||||
|
className='bg-transparent border border-gray-500 rounded-xl w-[300px] p-2'
|
||||||
|
label=''
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex gap-4 justify-center mt-10'>
|
||||||
|
<Button
|
||||||
|
label={t('confrim.yes')}
|
||||||
|
onClick={() => props.onConfrim(props.isHasDescription ? description : undefined)}
|
||||||
|
isLoading={props.isLoading}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
label={t('confrim.cancel')}
|
||||||
|
className='bg-transparent text-black border border-primary'
|
||||||
|
onClick={props.close}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DefaulModal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalConfrim
|
||||||
+17
-2
@@ -219,14 +219,29 @@
|
|||||||
"service": "سرویس",
|
"service": "سرویس",
|
||||||
"status": "وضعیت تایید",
|
"status": "وضعیت تایید",
|
||||||
"status_paid": "وضعیت پرداخت",
|
"status_paid": "وضعیت پرداخت",
|
||||||
"PENDING": "در انتظار پرداخت",
|
"PENDING": "در انتظار ",
|
||||||
"PAID": "پرداخت شده",
|
"PAID": "پرداخت شده",
|
||||||
"CANCELED": "لغو شده",
|
"CANCELED": "لغو شده",
|
||||||
"EXPIRED": "منقضی شده",
|
"EXPIRED": "منقضی شده",
|
||||||
|
"APPROVED": "تایید شده",
|
||||||
"real_person": "شخص حقیقی",
|
"real_person": "شخص حقیقی",
|
||||||
"fullName": "نام و نام خانوادگی",
|
"fullName": "نام و نام خانوادگی",
|
||||||
"compelete_financal_info_error": "برای دریافت فاکتور رسمی اطلاعات مالی خود را وارد کنید",
|
"compelete_financal_info_error": "برای دریافت فاکتور رسمی اطلاعات مالی خود را وارد کنید",
|
||||||
"compelete_financal_info": "تکمیل اطلاعات مالی"
|
"compelete_financal_info": "تکمیل اطلاعات مالی",
|
||||||
|
"get_factor": "دریافت پیش فاکتور",
|
||||||
|
"pay": "پرداخت",
|
||||||
|
"confrim_factor": "تایید فاکتور",
|
||||||
|
"sure_confrim_factor": "برای تایید فاکتور مطمئن هستید؟",
|
||||||
|
"accepted": "تایید شده",
|
||||||
|
"sure_confrim_pay": "آیا مطمئن هستید که مبلغ صورتحساب از کیف پول شما کسر شود؟",
|
||||||
|
"thank_pay_1": "ضمن تشکر از خرید شما",
|
||||||
|
"thank_pay_2": "مبلغ این صورت حساب پرداخت شده است."
|
||||||
|
},
|
||||||
|
"confrim": {
|
||||||
|
"subject": "حذف",
|
||||||
|
"content": "برای حذف این آیتم مطمئن هستید؟",
|
||||||
|
"yes": "بله",
|
||||||
|
"cancel": "لغو"
|
||||||
},
|
},
|
||||||
"edit": "ویرایش",
|
"edit": "ویرایش",
|
||||||
"transaction": {
|
"transaction": {
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import LegalInfo from './components/LegalInfo'
|
|||||||
import RealInfo from './components/RealInfo'
|
import RealInfo from './components/RealInfo'
|
||||||
import RegisterInfo from './components/RegisterInfo'
|
import RegisterInfo from './components/RegisterInfo'
|
||||||
import { clx } from '../../helpers/utils'
|
import { clx } from '../../helpers/utils'
|
||||||
|
import Button from '../../components/Button'
|
||||||
|
import ApproveInvoice from './components/ApproveInvoice'
|
||||||
|
import PayInvoice from './components/PayInvoice'
|
||||||
|
|
||||||
const ReceiptsDetail: FC = () => {
|
const ReceiptsDetail: FC = () => {
|
||||||
|
|
||||||
@@ -21,8 +24,10 @@ const ReceiptsDetail: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mt-4'>
|
<div className='mt-4'>
|
||||||
<div>
|
<div className='flex gap-6 items-center'>
|
||||||
{t('receip.detail_account')}
|
<div>{t('receip.detail_account')}</div>
|
||||||
|
|
||||||
|
<ApproveInvoice status={getInvoce.data?.data?.invoice?.status} id={id ? id : ''} refetch={getInvoce.refetch} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -107,13 +112,17 @@ const ReceiptsDetail: FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='bg-white xl:w-sidebar text-sm h-fit rounded-3xl p-8'>
|
<div className='bg-white xl:w-sidebar text-sm h-fit rounded-3xl p-8'>
|
||||||
|
<div className='p-6 bg-green-50 rounded-2xl text-green-400 text-xs mb-6'>
|
||||||
|
<p>{t('receip.thank_pay_1')}</p>
|
||||||
|
<p className='mt-1'>{t('receip.thank_pay_2')}</p>
|
||||||
|
</div>
|
||||||
<div className='flex justify-between items-center'>
|
<div className='flex justify-between items-center'>
|
||||||
<div>
|
<div>
|
||||||
{t('receip.receip_information')}
|
{t('receip.receip_information')}
|
||||||
</div>
|
</div>
|
||||||
<div className={clx(
|
<div className={clx(
|
||||||
'border border-orange-400 text-orange-400 rounded-lg text-[9px] h-6 flex items-center px-1',
|
'border border-orange-400 text-orange-400 rounded-lg text-[9px] h-6 flex items-center px-1',
|
||||||
getInvoce.data?.data?.invoice?.status === 'PAID' ? 'border-green-400 text-green-400' : getInvoce.data?.data?.invoice?.status !== 'PENDING' ? 'border-red-400 text-red-400' : 'border-orange-400 text-orange-400'
|
getInvoce.data?.data?.invoice?.status === 'PAID' || getInvoce.data?.data?.invoice?.status === 'APPROVED' ? 'border-green-400 text-green-400' : getInvoce.data?.data?.invoice?.status !== 'PENDING' ? 'border-red-400 text-red-400' : 'border-orange-400 text-orange-400'
|
||||||
)}>
|
)}>
|
||||||
<div>{t(`receip.${getInvoce.data?.data?.invoice?.status}`)}</div>
|
<div>{t(`receip.${getInvoce.data?.data?.invoice?.status}`)}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -152,6 +161,20 @@ const ReceiptsDetail: FC = () => {
|
|||||||
{t(`receip.${getInvoce.data?.data?.invoice?.status}`)}
|
{t(`receip.${getInvoce.data?.data?.invoice?.status}`)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
getInvoce.data?.data?.invoice?.status === 'APPROVED' &&
|
||||||
|
<div className='flex gap-4 items-center mt-8'>
|
||||||
|
<Button
|
||||||
|
label={t('receip.get_factor')}
|
||||||
|
className='bg-[#E8E8E8] text-description text-xs'
|
||||||
|
/>
|
||||||
|
<PayInvoice
|
||||||
|
id={id ? id : ''}
|
||||||
|
refetch={getInvoce.refetch}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import { Fragment, FC, useState } from 'react'
|
||||||
|
import Button from '../../../components/Button'
|
||||||
|
import { TickCircle } from 'iconsax-react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import ModalConfrim from '../../../components/ModalConfrim'
|
||||||
|
import { useApproveInvoice } from '../hooks/useReceiptData'
|
||||||
|
import { ErrorType } from '../../../helpers/types'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
import { clx } from '../../../helpers/utils'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
id: string,
|
||||||
|
refetch: () => void,
|
||||||
|
status: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const ApproveInvoice: FC<Props> = ({ id, refetch, status }) => {
|
||||||
|
|
||||||
|
const approveInvoce = useApproveInvoice()
|
||||||
|
const [showModal, setShowModal] = useState<boolean>(false)
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
|
||||||
|
const handleConfrim = () => {
|
||||||
|
approveInvoce.mutate(id, {
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(t('success'))
|
||||||
|
refetch()
|
||||||
|
setShowModal(false)
|
||||||
|
},
|
||||||
|
onError: (error: ErrorType) => {
|
||||||
|
toast.error(error.response?.data?.error.message[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'PENDING' || status === 'APPROVED')
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Button
|
||||||
|
onClick={() => status === 'PENDING' ? setShowModal(true) : null}
|
||||||
|
className={clx(
|
||||||
|
'px-9 w-fit bg-white bg-opacity-70 text-description',
|
||||||
|
status === 'APPROVED' && 'bg-green-300 text-[#00BA4B] bg-opacity-10'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className='flex gap-2.5'>
|
||||||
|
<TickCircle
|
||||||
|
size={20}
|
||||||
|
color={status === 'PENDING' ? '#888888' : '#00BA4B'}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
status === 'APPROVED' ?
|
||||||
|
t('receip.accepted')
|
||||||
|
:
|
||||||
|
t('receip.confrim_factor')
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<ModalConfrim
|
||||||
|
isOpen={showModal}
|
||||||
|
close={() => setShowModal(false)}
|
||||||
|
onConfrim={handleConfrim}
|
||||||
|
label={t('receip.sure_confrim_pay')}
|
||||||
|
isLoading={approveInvoce.isPending}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
else return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ApproveInvoice
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { FC, Fragment, useState } from 'react'
|
||||||
|
import Button from '../../../components/Button'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { usePayInvoice } from '../hooks/useReceiptData'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
import { ErrorType } from '../../../helpers/types'
|
||||||
|
import ModalConfrim from '../../../components/ModalConfrim'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
id: string,
|
||||||
|
refetch: () => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
const PayInvoice: FC<Props> = ({ id, refetch }) => {
|
||||||
|
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
const [showModal, setShowModal] = useState<boolean>(false)
|
||||||
|
const payInvoice = usePayInvoice()
|
||||||
|
|
||||||
|
|
||||||
|
const handleConfrim = () => {
|
||||||
|
payInvoice.mutate(id, {
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(t('success'))
|
||||||
|
refetch()
|
||||||
|
setShowModal(false)
|
||||||
|
},
|
||||||
|
onError: (error: ErrorType) => {
|
||||||
|
toast.error(error.response?.data?.error.message[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Button
|
||||||
|
label={t('receip.pay')}
|
||||||
|
onClick={() => setShowModal(true)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ModalConfrim
|
||||||
|
isOpen={showModal}
|
||||||
|
close={() => setShowModal(false)}
|
||||||
|
onConfrim={handleConfrim}
|
||||||
|
label={t('receip.sure_confrim_pay')}
|
||||||
|
isLoading={payInvoice.isPending}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PayInvoice
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
import * as api from "../service/ReceiptService";
|
import * as api from "../service/ReceiptService";
|
||||||
|
|
||||||
export const useGetInvoices = (status: string) => {
|
export const useGetInvoices = (status: string) => {
|
||||||
@@ -15,3 +15,15 @@ export const useGetInvoiceDetail = (id: string) => {
|
|||||||
enabled: !!id,
|
enabled: !!id,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useApproveInvoice = () => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (variables: string) => api.approveInvoice(variables),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const usePayInvoice = () => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (variables: string) => api.payInvoice(variables),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -9,3 +9,13 @@ export const getInvoiceDetail = async (id: string) => {
|
|||||||
const { data } = await axios.get(`/invoices/${id}`);
|
const { data } = await axios.get(`/invoices/${id}`);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const approveInvoice = async (id: string) => {
|
||||||
|
const { data } = await axios.patch(`/invoices/${id}/approve`);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const payInvoice = async (id: string) => {
|
||||||
|
const { data } = await axios.post(`/invoices/${id}/pay`);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user