mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 01:40:51 +00:00
4.8.10 test (#2470)
* i18n * perf: invoice type * fix: helper line change error * perf: base64 image * perf: app list ui * perf: upload max size check * perf: init system plugin * perf: dataset list ui * perf: http node ui * perf: ui * perf: invoice tip * fix: ts * perf: invoice table * perf: null check
This commit is contained in:
@@ -409,7 +409,7 @@ const PlanUsage = () => {
|
||||
|
||||
return standardPlan ? (
|
||||
<Box mt={[6, 0]}>
|
||||
<Flex fontSize={'lg'} h={'30px'}>
|
||||
<Flex fontSize={['md', 'lg']} h={'30px'}>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon mr={2} name={'support/account/plans'} w={'20px'} />
|
||||
{t('common:support.wallet.subscription.Team plan and usage')}
|
||||
@@ -428,7 +428,7 @@ const PlanUsage = () => {
|
||||
borderColor={'borderColor.low'}
|
||||
borderRadius={'md'}
|
||||
>
|
||||
<Flex px={[5, 7]} py={[3, 6]}>
|
||||
<Flex px={[5, 7]} py={[3, 6]} whiteSpace={'nowrap'}>
|
||||
<Box flex={'1 0 0'}>
|
||||
<Box color={'myGray.600'} fontSize="sm">
|
||||
{t('common:support.wallet.subscription.Current plan')}
|
||||
@@ -475,8 +475,10 @@ const PlanUsage = () => {
|
||||
>
|
||||
<Flex>
|
||||
<Flex flex={'1 0 0'} alignItems={'flex-end'}>
|
||||
<Box fontSize={'md'}>{t('common:info.resource')}</Box>
|
||||
<Box fontSize={'xs'} color={'myGray.500'}>
|
||||
<Box fontSize={'md'} fontWeight={'bold'} color={'myGray.900'}>
|
||||
{t('common:info.resource')}
|
||||
</Box>
|
||||
<Box ml={1} display={['none', 'block']} fontSize={'xs'} color={'myGray.500'}>
|
||||
{t('common:info.include')}
|
||||
</Box>
|
||||
</Flex>
|
||||
|
@@ -32,52 +32,25 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { getTeamInvoiceHeader } from '@/web/support/user/team/api';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
type chosenBillDataType = {
|
||||
_id: string;
|
||||
price: number;
|
||||
};
|
||||
|
||||
const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
|
||||
const [chosenBillDataList, setChosenBillDataList] = useState<chosenBillDataType[]>([]);
|
||||
const [totalPrice, setTotalPrice] = useState(0);
|
||||
const [formData, setFormData] = useState<TeamInvoiceHeaderType>({
|
||||
teamName: '',
|
||||
unifiedCreditCode: '',
|
||||
companyAddress: '',
|
||||
companyPhone: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
needSpecialInvoice: undefined,
|
||||
emailAddress: ''
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
const {
|
||||
isOpen: isOpenSettleModal,
|
||||
onOpen: onOpenSettleModal,
|
||||
onClose: onCloseSettleModal
|
||||
} = useDisclosure();
|
||||
|
||||
const handleChange = useCallback((e: any) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
||||
}, []);
|
||||
|
||||
const handleRatiosChange = useCallback((v: string) => {
|
||||
setFormData((prev) => ({ ...prev, needSpecialInvoice: v === 'true' }));
|
||||
}, []);
|
||||
|
||||
const isHeaderValid = useCallback((v: TeamInvoiceHeaderType) => {
|
||||
const emailRegex = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
|
||||
for (const [key, value] of Object.entries(v)) {
|
||||
if (typeof value === 'string' && value.trim() === '') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return emailRegex.test(v.emailAddress);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
loading: isLoading,
|
||||
data: billsList,
|
||||
@@ -86,12 +59,23 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
||||
manual: false
|
||||
});
|
||||
|
||||
const { run: handleSubmitInvoice, loading: isSubmitting } = useRequest2(
|
||||
() =>
|
||||
const handleSingleCheck = useCallback(
|
||||
(item: invoiceBillDataType) => {
|
||||
if (chosenBillDataList.find((bill) => bill._id === item._id)) {
|
||||
setChosenBillDataList(chosenBillDataList.filter((bill) => bill._id !== item._id));
|
||||
} else {
|
||||
setChosenBillDataList([...chosenBillDataList, { _id: item._id, price: item.price }]);
|
||||
}
|
||||
},
|
||||
[chosenBillDataList]
|
||||
);
|
||||
|
||||
const { runAsync: onSubmitApply, loading: isSubmitting } = useRequest2(
|
||||
(data) =>
|
||||
submitInvoice({
|
||||
amount: totalPrice,
|
||||
billIdList: chosenBillDataList.map((item) => item._id),
|
||||
...formData
|
||||
...data
|
||||
}),
|
||||
{
|
||||
manual: true,
|
||||
@@ -104,39 +88,29 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
||||
}
|
||||
);
|
||||
|
||||
const inputForm = useForm<TeamInvoiceHeaderType>({
|
||||
defaultValues: {
|
||||
teamName: '',
|
||||
unifiedCreditCode: '',
|
||||
companyAddress: '',
|
||||
companyPhone: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
needSpecialInvoice: false,
|
||||
emailAddress: ''
|
||||
}
|
||||
});
|
||||
const { loading: isLoadingHeader } = useRequest2(() => getTeamInvoiceHeader(), {
|
||||
manual: false,
|
||||
onSuccess: (res) => setFormData(res)
|
||||
onSuccess: (res) => inputForm.reset(res)
|
||||
});
|
||||
|
||||
const handleSubmit = useCallback(async () => {
|
||||
if (!isHeaderValid(formData)) {
|
||||
toast({
|
||||
title: t('common:support.wallet.invoice_data.in_valid'),
|
||||
status: 'info'
|
||||
});
|
||||
return;
|
||||
}
|
||||
handleSubmitInvoice();
|
||||
}, [formData, handleSubmitInvoice, isHeaderValid, t, toast]);
|
||||
|
||||
const handleBack = useCallback(() => {
|
||||
setChosenBillDataList([]);
|
||||
getInvoiceBills();
|
||||
onCloseSettleModal();
|
||||
}, [getInvoiceBills, onCloseSettleModal]);
|
||||
|
||||
const handleSingleCheck = useCallback(
|
||||
(item: invoiceBillDataType) => {
|
||||
if (chosenBillDataList.find((bill) => bill._id === item._id)) {
|
||||
setChosenBillDataList(chosenBillDataList.filter((bill) => bill._id !== item._id));
|
||||
} else {
|
||||
setChosenBillDataList([...chosenBillDataList, { _id: item._id, price: item.price }]);
|
||||
}
|
||||
},
|
||||
[chosenBillDataList]
|
||||
);
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
isOpen={true}
|
||||
@@ -258,11 +232,7 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
||||
</Box>
|
||||
<MyBox isLoading={isLoadingHeader}>
|
||||
<Flex justify={'center'}>
|
||||
<InvoiceHeaderSingleForm
|
||||
formData={formData}
|
||||
handleChange={handleChange}
|
||||
handleRatiosChange={handleRatiosChange}
|
||||
/>
|
||||
<InvoiceHeaderSingleForm inputForm={inputForm} />
|
||||
</Flex>
|
||||
</MyBox>
|
||||
<Flex
|
||||
@@ -289,7 +259,7 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
||||
</Box>
|
||||
</Flex>
|
||||
</Button>
|
||||
<Button isLoading={isSubmitting} px="0" onClick={handleSubmit}>
|
||||
<Button isLoading={isSubmitting} px="0" onClick={inputForm.handleSubmit(onSubmitApply)}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box px={'1.25rem'} py={'0.5rem'}>
|
||||
{t('common:common.Confirm')}
|
||||
|
@@ -6,19 +6,22 @@ import { useTranslation } from 'next-i18next';
|
||||
import ApplyInvoiceModal from './ApplyInvoiceModal';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
export const InvoiceTabEnum = {
|
||||
bill: 'bill',
|
||||
invoice: 'invoice',
|
||||
invoiceHeader: 'invoiceHeader'
|
||||
};
|
||||
export enum InvoiceTabEnum {
|
||||
bill = 'bill',
|
||||
invoice = 'invoice',
|
||||
invoiceHeader = 'invoiceHeader'
|
||||
}
|
||||
|
||||
const BillTable = dynamic(() => import('./BillTable'));
|
||||
const InvoiceHeaderForm = dynamic(() => import('./InvoiceHeaderForm'));
|
||||
const InvoiceTable = dynamic(() => import('./InvoiceTable'));
|
||||
const BillAndInvoice = () => {
|
||||
const [isOpenInvoiceModal, setIsOpenInvoiceModal] = useState(false);
|
||||
const router = useRouter();
|
||||
const invoiceTab = (router.query.invoiceTab as string) || InvoiceTabEnum.bill;
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const { invoiceTab = InvoiceTabEnum.bill } = router.query as { invoiceTab: `${InvoiceTabEnum}` };
|
||||
|
||||
const [isOpenInvoiceModal, setIsOpenInvoiceModal] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box p={['1rem', '2rem']}>
|
||||
@@ -36,7 +39,7 @@ const BillAndInvoice = () => {
|
||||
onChange={(e) => {
|
||||
router.replace({
|
||||
query: {
|
||||
currentTab: router.query.currentTab,
|
||||
...router.query,
|
||||
invoiceTab: e
|
||||
}
|
||||
});
|
||||
|
@@ -101,6 +101,7 @@ const BillTable = () => {
|
||||
isLoading={isLoading || isRefreshing}
|
||||
position={'relative'}
|
||||
h={'100%'}
|
||||
minH={'50vh'}
|
||||
overflow={'overlay'}
|
||||
>
|
||||
<TableContainer>
|
||||
@@ -198,6 +199,10 @@ function BillDetailModal({ bill, onClose }: { bill: BillSchemaType; onClose: ()
|
||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.usage.Time')}:</FormLabel>
|
||||
<Box>{dayjs(bill.createTime).format('YYYY/MM/DD HH:mm:ss')}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.bill.Type')}:</FormLabel>
|
||||
<Box>{t(billTypeMap[bill.type]?.label as any)}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.bill.Status')}:</FormLabel>
|
||||
<Box>{t(billStatusMap[bill.status]?.label as any)}</Box>
|
||||
@@ -212,14 +217,18 @@ function BillDetailModal({ bill, onClose }: { bill: BillSchemaType; onClose: ()
|
||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.Amount')}:</FormLabel>
|
||||
<Box>{commonT('common:pay.yuan', { amount: formatStorePrice2Read(bill.price) })}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.bill.Type')}:</FormLabel>
|
||||
<Box>{t(billTypeMap[bill.type]?.label as any)}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.has_invoice')}:</FormLabel>
|
||||
<Box>{bill.hasInvoice ? t('common:yes') : t('common:no')}</Box>
|
||||
</Flex>
|
||||
{bill.metadata && (
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.has_invoice')}:</FormLabel>
|
||||
{bill.metadata.payWay === 'balance' ? (
|
||||
t('user:bill.not_need_invoice')
|
||||
) : (
|
||||
<Box>
|
||||
{(bill.metadata.payWay = bill.hasInvoice ? t('common:yes') : t('common:no'))}
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
{!!bill.metadata?.subMode && (
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<FormLabel flex={'0 0 120px'}>
|
||||
|
@@ -1,56 +1,28 @@
|
||||
import Divider from '@/pages/app/detail/components/WorkflowComponents/Flow/components/Divider';
|
||||
import { getTeamInvoiceHeader, updateTeamInvoiceHeader } from '@/web/support/user/team/api';
|
||||
import { Box, Button, Flex, Input, Radio, RadioGroup, Stack } from '@chakra-ui/react';
|
||||
import { Box, Button, Flex, HStack, Input, InputProps, Radio, RadioGroup } from '@chakra-ui/react';
|
||||
import { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
|
||||
const InputItem = ({
|
||||
label,
|
||||
value,
|
||||
onChange,
|
||||
name
|
||||
}: {
|
||||
label: string;
|
||||
value: string;
|
||||
onChange: (e: any) => void;
|
||||
name: string;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<Flex justify={'space-between'} flexDir={['column', 'row']}>
|
||||
<Box fontSize={'14px'} lineHeight={'2rem'}>
|
||||
{label}
|
||||
</Box>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
border={'1px solid'}
|
||||
borderColor={'myGray.200'}
|
||||
w={'21.25rem'}
|
||||
focusBorderColor="myGray.200"
|
||||
placeholder={label}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
name={name}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
};
|
||||
import { UseFormReturn, useForm } from 'react-hook-form';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
|
||||
export const InvoiceHeaderSingleForm = ({
|
||||
formData,
|
||||
handleChange,
|
||||
handleRatiosChange
|
||||
inputForm
|
||||
}: {
|
||||
formData: TeamInvoiceHeaderType;
|
||||
handleChange: (e: any) => void;
|
||||
handleRatiosChange: (v: string) => void;
|
||||
inputForm: UseFormReturn<TeamInvoiceHeaderType, any>;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { watch, register } = inputForm;
|
||||
const needSpecialInvoice = watch('needSpecialInvoice');
|
||||
|
||||
const styles: InputProps = {
|
||||
bg: 'myGray.50',
|
||||
w: '21.25rem'
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
@@ -61,138 +33,185 @@ export const InvoiceHeaderSingleForm = ({
|
||||
color={'myGray.900'}
|
||||
fontSize={'14px'}
|
||||
>
|
||||
<InputItem
|
||||
label={t('common:support.wallet.invoice_data.organization_name')}
|
||||
value={formData.teamName}
|
||||
onChange={handleChange}
|
||||
name="teamName"
|
||||
/>
|
||||
<InputItem
|
||||
label={t('common:support.wallet.invoice_data.unit_code')}
|
||||
value={formData.unifiedCreditCode}
|
||||
onChange={handleChange}
|
||||
name="unifiedCreditCode"
|
||||
/>
|
||||
<InputItem
|
||||
label={t('common:support.wallet.invoice_data.company_address')}
|
||||
value={formData.companyAddress}
|
||||
onChange={handleChange}
|
||||
name="companyAddress"
|
||||
/>
|
||||
<InputItem
|
||||
label={t('common:support.wallet.invoice_data.company_phone')}
|
||||
value={formData.companyPhone}
|
||||
onChange={handleChange}
|
||||
name="companyPhone"
|
||||
/>
|
||||
<InputItem
|
||||
label={t('common:support.wallet.invoice_data.bank')}
|
||||
value={formData.bankName}
|
||||
onChange={handleChange}
|
||||
name="bankName"
|
||||
/>
|
||||
<InputItem
|
||||
label={t('common:support.wallet.invoice_data.bank_account')}
|
||||
value={formData.bankAccount}
|
||||
onChange={handleChange}
|
||||
name="bankAccount"
|
||||
/>
|
||||
<Flex justify={'space-between'} flexDir={['column', 'row']}>
|
||||
<Box fontSize={'14px'} lineHeight={'2rem'}>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required>
|
||||
{t('common:support.wallet.invoice_data.organization_name')}
|
||||
</FormLabel>
|
||||
<Input
|
||||
{...styles}
|
||||
placeholder={t('common:support.wallet.invoice_data.organization_name')}
|
||||
{...register('teamName', { required: true })}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required>{t('common:support.wallet.invoice_data.unit_code')}</FormLabel>
|
||||
<Input
|
||||
{...styles}
|
||||
placeholder={t('common:support.wallet.invoice_data.unit_code')}
|
||||
{...register('unifiedCreditCode', { required: true })}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required={!!needSpecialInvoice}>
|
||||
{t('common:support.wallet.invoice_data.company_address')}
|
||||
</FormLabel>
|
||||
<Input
|
||||
{...styles}
|
||||
placeholder={t('common:support.wallet.invoice_data.company_address')}
|
||||
{...register('companyAddress', { required: !!needSpecialInvoice })}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required={!!needSpecialInvoice}>
|
||||
{t('common:support.wallet.invoice_data.company_phone')}
|
||||
</FormLabel>
|
||||
<Input
|
||||
{...styles}
|
||||
placeholder={t('common:support.wallet.invoice_data.company_phone')}
|
||||
{...register('companyPhone', { required: !!needSpecialInvoice })}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required={!!needSpecialInvoice}>
|
||||
{t('common:support.wallet.invoice_data.bank')}
|
||||
</FormLabel>
|
||||
<Input
|
||||
{...styles}
|
||||
placeholder={t('common:support.wallet.invoice_data.bank')}
|
||||
{...register('bankName', { required: !!needSpecialInvoice })}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required={!!needSpecialInvoice}>
|
||||
{t('common:support.wallet.invoice_data.bank_account')}
|
||||
</FormLabel>
|
||||
<Input
|
||||
{...styles}
|
||||
placeholder={t('common:support.wallet.invoice_data.bank_account')}
|
||||
{...register('bankAccount', { required: !!needSpecialInvoice })}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required>
|
||||
{t('common:support.wallet.invoice_data.need_special_invoice')}
|
||||
</Box>
|
||||
</FormLabel>
|
||||
{/* @ts-ignore */}
|
||||
<RadioGroup
|
||||
value={
|
||||
formData.needSpecialInvoice === undefined
|
||||
? ''
|
||||
: formData.needSpecialInvoice.toString()
|
||||
}
|
||||
onChange={handleRatiosChange}
|
||||
value={`${needSpecialInvoice}`}
|
||||
onChange={(e) => {
|
||||
inputForm.setValue('needSpecialInvoice', e === 'true');
|
||||
}}
|
||||
w={'21.25rem'}
|
||||
>
|
||||
<Stack direction="row" h={'2rem'}>
|
||||
<HStack h={'2rem'}>
|
||||
<Radio value="true" pr={'1rem'}>
|
||||
<Box fontSize={'14px'}>{t('common:yes')}</Box>
|
||||
</Radio>
|
||||
<Radio value="false">
|
||||
<Box fontSize={'14px'}>{t('common:no')}</Box>
|
||||
</Radio>
|
||||
</Stack>
|
||||
</HStack>
|
||||
</RadioGroup>
|
||||
</Flex>
|
||||
<Box w={'100%'}>
|
||||
<Divider showBorderBottom={false} />
|
||||
</Box>
|
||||
<InputItem
|
||||
label={t('common:support.wallet.invoice_data.email')}
|
||||
value={formData.emailAddress}
|
||||
onChange={handleChange}
|
||||
name="emailAddress"
|
||||
/>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={['flex-start', 'center']}
|
||||
flexDir={['column', 'row']}
|
||||
>
|
||||
<FormLabel required>{t('common:support.wallet.invoice_data.email')}</FormLabel>
|
||||
<Input
|
||||
{...styles}
|
||||
placeholder={t('common:support.wallet.invoice_data.email')}
|
||||
{...register('emailAddress', {
|
||||
required: true,
|
||||
pattern: {
|
||||
value: /(^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$)/,
|
||||
message: t('user:password.email_phone_error')
|
||||
}
|
||||
})}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const InvoiceHeaderForm = () => {
|
||||
const [formData, setFormData] = useState<TeamInvoiceHeaderType>({
|
||||
teamName: '',
|
||||
unifiedCreditCode: '',
|
||||
companyAddress: '',
|
||||
companyPhone: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
needSpecialInvoice: undefined,
|
||||
emailAddress: ''
|
||||
const inputForm = useForm<TeamInvoiceHeaderType>({
|
||||
defaultValues: {
|
||||
teamName: '',
|
||||
unifiedCreditCode: '',
|
||||
companyAddress: '',
|
||||
companyPhone: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
needSpecialInvoice: false,
|
||||
emailAddress: ''
|
||||
}
|
||||
});
|
||||
|
||||
const { loading: isLoading } = useRequest2(() => getTeamInvoiceHeader(), {
|
||||
manual: false,
|
||||
onSuccess: (data) => {
|
||||
setFormData(data);
|
||||
console.log(data, '--');
|
||||
inputForm.reset(data);
|
||||
}
|
||||
});
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const handleChange = useCallback((e: any) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
||||
}, []);
|
||||
const handleRatiosChange = useCallback((v: string) => {
|
||||
setFormData((prev) => ({ ...prev, needSpecialInvoice: v === 'true' }));
|
||||
}, []);
|
||||
const isHeaderValid = useCallback((v: TeamInvoiceHeaderType) => {
|
||||
const emailRegex = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
|
||||
return emailRegex.test(v.emailAddress);
|
||||
}, []);
|
||||
const { loading: isSubmitting, run: handleSubmit } = useRequest2(
|
||||
() => updateTeamInvoiceHeader(formData),
|
||||
|
||||
const { loading: isSubmitting, runAsync: onUpdateHeader } = useRequest2(
|
||||
(data: TeamInvoiceHeaderType) => updateTeamInvoiceHeader(data),
|
||||
{
|
||||
manual: true,
|
||||
successToast: t('common:common.Save Success'),
|
||||
errorToast: t('common:common.Save Failed')
|
||||
}
|
||||
);
|
||||
const onSubmit = useCallback(() => {
|
||||
if (!isHeaderValid(formData)) {
|
||||
toast({
|
||||
title: t('common:support.wallet.invoice_data.in_valid'),
|
||||
status: 'info'
|
||||
});
|
||||
return;
|
||||
}
|
||||
handleSubmit();
|
||||
}, [handleSubmit, formData, isHeaderValid, toast, t]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MyBox isLoading={isLoading} pt={['1rem', '3.5rem']}>
|
||||
<Flex w={'100%'} overflow={'auto'} justify={'center'} flexDir={'column'} align={'center'}>
|
||||
<InvoiceHeaderSingleForm
|
||||
formData={formData}
|
||||
handleChange={handleChange}
|
||||
handleRatiosChange={handleRatiosChange}
|
||||
/>
|
||||
<InvoiceHeaderSingleForm inputForm={inputForm} />
|
||||
<Flex w={'100%'} justify={'center'} mt={'3rem'}>
|
||||
<Button variant={'primary'} px="0" onClick={onSubmit} isLoading={isSubmitting}>
|
||||
<Button
|
||||
variant={'primary'}
|
||||
px="0"
|
||||
onClick={inputForm.handleSubmit(onUpdateHeader)}
|
||||
isLoading={isSubmitting}
|
||||
>
|
||||
<Flex alignItems={'center'} px={'20px'}>
|
||||
<Box px={'1.25rem'} py={'0.5rem'}>
|
||||
{t('common:common.Save')}
|
||||
|
@@ -197,11 +197,11 @@ function InvoiceDetailModal({
|
||||
);
|
||||
}
|
||||
|
||||
function LabelItem({ label, value }: { label: string; value: string }) {
|
||||
function LabelItem({ label, value }: { label: string; value?: string }) {
|
||||
return (
|
||||
<Flex alignItems={'center'} justify={'space-between'}>
|
||||
<FormLabel flex={'0 0 120px'}>{label}</FormLabel>
|
||||
<Box>{value}</Box>
|
||||
<Box>{value || '-'}</Box>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user