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": "سرویس",
|
||||
"status": "وضعیت تایید",
|
||||
"status_paid": "وضعیت پرداخت",
|
||||
"PENDING": "در انتظار پرداخت",
|
||||
"PENDING": "در انتظار ",
|
||||
"PAID": "پرداخت شده",
|
||||
"CANCELED": "لغو شده",
|
||||
"EXPIRED": "منقضی شده",
|
||||
"APPROVED": "تایید شده",
|
||||
"real_person": "شخص حقیقی",
|
||||
"fullName": "نام و نام خانوادگی",
|
||||
"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": "ویرایش",
|
||||
"transaction": {
|
||||
|
||||
@@ -11,6 +11,9 @@ import LegalInfo from './components/LegalInfo'
|
||||
import RealInfo from './components/RealInfo'
|
||||
import RegisterInfo from './components/RegisterInfo'
|
||||
import { clx } from '../../helpers/utils'
|
||||
import Button from '../../components/Button'
|
||||
import ApproveInvoice from './components/ApproveInvoice'
|
||||
import PayInvoice from './components/PayInvoice'
|
||||
|
||||
const ReceiptsDetail: FC = () => {
|
||||
|
||||
@@ -21,8 +24,10 @@ const ReceiptsDetail: FC = () => {
|
||||
|
||||
return (
|
||||
<div className='mt-4'>
|
||||
<div>
|
||||
{t('receip.detail_account')}
|
||||
<div className='flex gap-6 items-center'>
|
||||
<div>{t('receip.detail_account')}</div>
|
||||
|
||||
<ApproveInvoice status={getInvoce.data?.data?.invoice?.status} id={id ? id : ''} refetch={getInvoce.refetch} />
|
||||
</div>
|
||||
|
||||
{
|
||||
@@ -107,13 +112,17 @@ const ReceiptsDetail: FC = () => {
|
||||
</div>
|
||||
|
||||
<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>
|
||||
{t('receip.receip_information')}
|
||||
</div>
|
||||
<div className={clx(
|
||||
'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>
|
||||
@@ -152,6 +161,20 @@ const ReceiptsDetail: FC = () => {
|
||||
{t(`receip.${getInvoce.data?.data?.invoice?.status}`)}
|
||||
</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>
|
||||
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
export const useGetInvoices = (status: string) => {
|
||||
@@ -15,3 +15,15 @@ export const useGetInvoiceDetail = (id: string) => {
|
||||
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}`);
|
||||
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