메뉴 권한 및 ui 수정
This commit is contained in:
@@ -19,7 +19,6 @@ import {
|
||||
useSetFooterMode
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { useAllTransactioCancleInfoMutation } from '@/entities/transaction/api/use-all-transaction-cancel-info-mutation';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { useStore } from '@/shared/model/store';
|
||||
import { AllTransactionCancelPreventBond } from '@/entities/transaction/ui/all-transaction-cancel-prevent-bond';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
|
||||
@@ -32,13 +32,13 @@ import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AllTransactionDetail } from '@/entities/transaction/ui/detail/all-transaction-detail';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
|
||||
/* 거래내역조회 31 */
|
||||
export const AllTransactionListPage = () => {
|
||||
const menuGrantsByKey = useStore.getState().UserStore.menuGrantsByKey;
|
||||
const myGrants = menuGrantsByKey['31'];
|
||||
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const { t, i18n } = useTranslation();
|
||||
const userMid = useStore.getState().UserStore.mid;
|
||||
|
||||
@@ -244,7 +244,7 @@ export const AllTransactionListPage = () => {
|
||||
|
||||
return nameMap[name] || name;
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
callServiceCodeOptions();
|
||||
}, []);
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useBillingDetailMutation } from '@/entities/transaction/api/use-billing-detail-mutation';
|
||||
import { BillingInfoSection } from '@/entities/transaction/ui/section/billing-info-section';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
TransactionCategory,
|
||||
BillingDetailParams,
|
||||
BillingDetailResponse,
|
||||
BillingInfo,
|
||||
AmountInfo
|
||||
} from '@/entities/transaction/model/types';
|
||||
import {
|
||||
useSetOnBack,
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { C } from 'node_modules/react-router/dist/development/index-react-server-client-DRhjXpk2.mjs';
|
||||
import { AmountInfoSection } from '@/entities/transaction/ui/section/amount-info-section';
|
||||
|
||||
export const BillingDetailPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t, i18n } = useTranslation();
|
||||
const location = useLocation();
|
||||
const tid = location?.state.tid;
|
||||
const serviceCode = location?.state.serviceCode;
|
||||
|
||||
|
||||
const [billingInfo, setBillingInfo] = useState<BillingInfo>();
|
||||
const [amountInfo, setAmountInfo] = useState<AmountInfo>();
|
||||
|
||||
useSetHeaderTitle(t('billing.detailTitle'));
|
||||
useSetHeaderType(HeaderType.RightClose);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.transaction.billing.list);
|
||||
});
|
||||
useSetFooterMode(false);
|
||||
|
||||
const { mutateAsync: billingDetail } = useBillingDetailMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let billingDetailParams: BillingDetailParams = {
|
||||
tid: tid
|
||||
};
|
||||
billingDetail(billingDetailParams).then((rs: BillingDetailResponse) => {
|
||||
setBillingInfo(rs);
|
||||
setAmountInfo({
|
||||
transactionAmount: rs.transactionAmount,
|
||||
buyerName: rs.buyerName
|
||||
})
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="txn-detail">
|
||||
<div className="txn-num-group">
|
||||
<div className="txn-amount">
|
||||
<div className="value">
|
||||
{ i18n.language === 'en' && <span className="unit">{ t('home.currencySymbol') }</span> }
|
||||
<NumericFormat
|
||||
value={ amountInfo?.transactionAmount }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
></NumericFormat>
|
||||
{ i18n.language !== 'en' && <span className="unit">{ t('home.currencyWon') }</span> }
|
||||
</div>
|
||||
</div>
|
||||
<div className="txn-mid">
|
||||
<span className="value">{ amountInfo?.buyerName }</span>
|
||||
</div>
|
||||
<div className="txn-doc"></div>
|
||||
</div>
|
||||
<div className="txn-divider"></div>
|
||||
<BillingInfoSection
|
||||
billingInfo={ billingInfo }
|
||||
></BillingInfoSection>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,161 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useCashReceiptDetailMutation } from '@/entities/transaction/api/use-cash-receipt-detail-mutation';
|
||||
import { IssueInfoSection } from '@/entities/transaction/ui/section/issue-info-section';
|
||||
import { DetailInfoSection } from '@/entities/transaction/ui/section/detail-info-section';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
TransactionCategory,
|
||||
CashReceiptDetailParams,
|
||||
DetailResponse,
|
||||
IssueInfo,
|
||||
DetailInfo,
|
||||
InfoSectionKeys,
|
||||
CashReceiptPurposeType,
|
||||
AmountInfo,
|
||||
CashReceiptPurposeUpdateParams,
|
||||
CashReceiptTransactionType
|
||||
} from '@/entities/transaction/model/types';
|
||||
import {
|
||||
useSetOnBack,
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { CashReceitPurposeUpdateBottomSheet } from '@/entities/transaction/ui/cash-receit-purpose-update-bottom-sheet';
|
||||
import { useCashReceiptPurposeUpdateMutation } from '@/entities/transaction/api/use-cash-receipt-purpose-update-mutation';
|
||||
import { AmountInfoSection } from '@/entities/transaction/ui/section/amount-info-section';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
|
||||
export const CashReceiptDetailPage = () => {
|
||||
const { navigate, reload } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
|
||||
const [amountInfo, setAmountInfo] = useState<AmountInfo>();
|
||||
const [issueInfo, setIssueInfo] = useState<IssueInfo>();
|
||||
const [detailInfo, setDetailInfo] = useState<DetailInfo>();
|
||||
const [showAmountInfo, setShowAmountInfo] = useState<boolean>(false);
|
||||
const [showDetailInfo, setShowDetailInfo] = useState<boolean>(false);
|
||||
const [bottomSheetOn, setBottomSheetOn] = useState<boolean>(false);
|
||||
const [purposeType, setPurposeType] = useState<string>();
|
||||
const [canDownloadReceipt, setCanDownloadReceipt] = useState<boolean>(false);
|
||||
|
||||
|
||||
useSetHeaderTitle(t('cashReceipt.detailTitle'));
|
||||
useSetHeaderType(HeaderType.RightClose);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.transaction.cashReceipt.list);
|
||||
});
|
||||
useSetFooterMode(false);
|
||||
|
||||
const tid = location?.state.tid
|
||||
|
||||
const { mutateAsync: cashReceiptDetail } = useCashReceiptDetailMutation();
|
||||
const { mutateAsync: cashReceiptPurposeUpdate } = useCashReceiptPurposeUpdateMutation();
|
||||
|
||||
const callPurposeUpdate = () => {
|
||||
let newPurpose = (purposeType === CashReceiptPurposeType.EXPENSE_PROOF)
|
||||
? CashReceiptPurposeType.INCOME_DEDUCTION: CashReceiptPurposeType.EXPENSE_PROOF;
|
||||
let params: CashReceiptPurposeUpdateParams = {
|
||||
tid: tid,
|
||||
newPurpose: newPurpose
|
||||
};
|
||||
cashReceiptPurposeUpdate(params).then((rs) => {
|
||||
setPurposeType(rs.afterPurposeType);
|
||||
setBottomSheetOn(false);
|
||||
snackBar('용도 변경을 성공하였습니다.', function(){
|
||||
reload();
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
const callDetail = () => {
|
||||
let cashReceitDetailParams: CashReceiptDetailParams = {
|
||||
tid: tid
|
||||
};
|
||||
cashReceiptDetail(cashReceitDetailParams).then((rs: DetailResponse) => {
|
||||
if(rs.amountDetail){
|
||||
rs.amountDetail.customerName = rs.customerName;
|
||||
}
|
||||
setAmountInfo(rs.amountDetail || {});
|
||||
setIssueInfo(rs.issueInfo || {});
|
||||
setDetailInfo(rs.detailInfo || {});
|
||||
setCanDownloadReceipt(rs.detailInfo?.canDownloadReceipt || false);
|
||||
if(rs.issueInfo){
|
||||
setPurposeType(rs.issueInfo.purpose);
|
||||
}
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
const onClickToOpenInfo = (infoSectionKey: InfoSectionKeys) => {
|
||||
if(infoSectionKey === InfoSectionKeys.Amount){
|
||||
setShowAmountInfo(!showAmountInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Detail){
|
||||
setShowDetailInfo(!showDetailInfo);
|
||||
}
|
||||
};
|
||||
|
||||
const onClickToPurposeUpdate = () => {
|
||||
setBottomSheetOn(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className={ `txn-detail ${(detailInfo?.canDownloadReceipt)? 'pb-86': ''}` }>
|
||||
<AmountInfoSection
|
||||
transactionCategory={ TransactionCategory.CashReceipt }
|
||||
amountInfo={ amountInfo }
|
||||
isOpen={ showAmountInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
purposeType={ purposeType }
|
||||
canDownloadReceipt={ canDownloadReceipt }
|
||||
></AmountInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<IssueInfoSection
|
||||
transactionCategory={ TransactionCategory.CashReceipt }
|
||||
issueInfo={ issueInfo }
|
||||
purposeType={ purposeType }
|
||||
></IssueInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
{ !!detailInfo &&
|
||||
<DetailInfoSection
|
||||
transactionCategory={ TransactionCategory.CashReceipt }
|
||||
detailInfo={ detailInfo }
|
||||
isOpen={ showDetailInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></DetailInfoSection>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{ (issueInfo?.transactionType === CashReceiptTransactionType.APPROVAL) &&
|
||||
(issueInfo?.processResult === '발급완료') &&
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToPurposeUpdate() }
|
||||
>{ t('cashReceipt.changePurpose') }</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<CashReceitPurposeUpdateBottomSheet
|
||||
setBottomSheetOn={ setBottomSheetOn }
|
||||
bottomSheetOn={ bottomSheetOn }
|
||||
callPurposeUpdate={ callPurposeUpdate }
|
||||
></CashReceitPurposeUpdateBottomSheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,209 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useEscrowDetailMutation } from '@/entities/transaction/api/use-escrow-detail-mutation';
|
||||
import { ImportantInfoSection } from '@/entities/transaction/ui/section/important-info-section';
|
||||
import { EscrowInfoSection } from '@/entities/transaction/ui/section/escrow-info-section';
|
||||
import { PaymentInfoSection } from '@/entities/transaction/ui/section/payment-info-section';
|
||||
import { TransactionInfoSection } from '@/entities/transaction/ui/section/transaction-info-section';
|
||||
import { SettlementInfoSection } from '@/entities/transaction/ui/section/settlement-info-section';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
TransactionCategory,
|
||||
EscrowDetailParams,
|
||||
DetailResponse,
|
||||
ImportantInfo,
|
||||
EscrowInfo,
|
||||
PaymentInfo,
|
||||
TransactionInfo,
|
||||
SettlementInfo,
|
||||
InfoSectionKeys,
|
||||
MerchantInfo,
|
||||
AmountInfo
|
||||
} from '@/entities/transaction/model/types';
|
||||
import {
|
||||
useSetOnBack,
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { EscrowMailResendBottomSheet } from '@/entities/transaction/ui/escrow-mail-resend-bottom-sheet';
|
||||
import { useEscrowMailResendMutation } from '@/entities/transaction/api/use-escrow-mail-resend-mutation';
|
||||
import { MerchantInfoSection } from '@/entities/transaction/ui/section/merchant-info-section';
|
||||
import { AmountInfoSection } from '@/entities/transaction/ui/section/amount-info-section';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
|
||||
export const EscrowDetailPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const paramTid = location?.state.tid;
|
||||
const serviceCode = location?.state.serviceCode;
|
||||
|
||||
const [amountInfo, setAmountInfo] = useState<AmountInfo>();
|
||||
const [importantInfo, setImportantInfo] = useState<ImportantInfo>();
|
||||
const [escrowInfo, setEscrowInfo] = useState<EscrowInfo>();
|
||||
const [paymentInfo, setPaymentInfo] = useState<PaymentInfo>();
|
||||
const [transactionInfo, setTransactionInfo] = useState<TransactionInfo>();
|
||||
const [settlementInfo, setSettlementInfo] = useState<SettlementInfo>();
|
||||
const [merchantInfo, setMerchantInfo] = useState<MerchantInfo>();
|
||||
|
||||
const [showAmountInfo, setShowAmountInfo] = useState<boolean>(false);
|
||||
const [showImportantInfo, setShowImportantInfo] = useState<boolean>(false);
|
||||
const [showEscroInfo, setShowEscroInfo] = useState<boolean>(false);
|
||||
const [showPaymentInfo, setShowPaymentInfo] = useState<boolean>(false);
|
||||
const [showTransactionInfo, setShowTransactionInfo] = useState<boolean>(false);
|
||||
const [showSettlementInfo, setShowSettlementInfo] = useState<boolean>(false);
|
||||
const [showMerchantInfo, setShowMerchantInfo] = useState<boolean>(false);
|
||||
|
||||
const [bottomSheetOn, setBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const [orderNumber, setOrderNumber] = useState<string>();
|
||||
const [tid, setTid] = useState<string | undefined>(paramTid);
|
||||
|
||||
useSetHeaderTitle(t('escrow.detailTitle'));
|
||||
useSetHeaderType(HeaderType.RightClose);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.transaction.escrow.list);
|
||||
});
|
||||
useSetFooterMode(false);
|
||||
|
||||
const { mutateAsync: escrowDetail } = useEscrowDetailMutation();
|
||||
const { mutateAsync: escrowMailResend } = useEscrowMailResendMutation()
|
||||
|
||||
const callDetail = () => {
|
||||
let escroDetailParams: EscrowDetailParams = {
|
||||
tid: tid || paramTid,
|
||||
};
|
||||
escrowDetail(escroDetailParams).then((rs: DetailResponse) => {
|
||||
setAmountInfo(rs.paymentInfo || {});
|
||||
setImportantInfo(rs.importantInfo || {});
|
||||
setEscrowInfo(rs.escrowInfo || {});
|
||||
setPaymentInfo(rs.paymentInfo || {});
|
||||
setTransactionInfo(rs.transactionInfo || {});
|
||||
setSettlementInfo(rs.settlementInfo || {});
|
||||
setMerchantInfo(rs.merchantInfo || {});
|
||||
|
||||
setOrderNumber(rs.importantInfo?.orderNumber);
|
||||
setTid(rs.importantInfo?.tid);
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
const onClickToShowMailResend = () => {
|
||||
setBottomSheetOn(true);
|
||||
};
|
||||
|
||||
const callMailResend = () => {
|
||||
let params = {
|
||||
orderNumber: orderNumber,
|
||||
tid: tid,
|
||||
};
|
||||
escrowMailResend(params).then((rs: any) => {
|
||||
console.log(rs);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToOpenInfo = (infoSectionKey: InfoSectionKeys) => {
|
||||
if(infoSectionKey === InfoSectionKeys.Amount){
|
||||
setShowAmountInfo(!showAmountInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Important){
|
||||
setShowImportantInfo(!showImportantInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Escrow){
|
||||
setShowEscroInfo(!showEscroInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Payment){
|
||||
setShowPaymentInfo(!showPaymentInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Transaction){
|
||||
setShowTransactionInfo(!showTransactionInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Settlement){
|
||||
setShowSettlementInfo(!showSettlementInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Merchant){
|
||||
setShowMerchantInfo(!showMerchantInfo);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content pb-86">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="txn-detail">
|
||||
<AmountInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
amountInfo={ amountInfo }
|
||||
isOpen={ showAmountInfo }
|
||||
tid={ tid }
|
||||
serviceCode={ serviceCode }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></AmountInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<ImportantInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
importantInfo={ importantInfo }
|
||||
></ImportantInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<EscrowInfoSection
|
||||
escrowInfo={ escrowInfo }
|
||||
isOpen={ showEscroInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></EscrowInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<PaymentInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
paymentInfo={ paymentInfo }
|
||||
isOpen={ showPaymentInfo }
|
||||
serviceCode={ serviceCode }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></PaymentInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<TransactionInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
transactionInfo={ transactionInfo }
|
||||
isOpen={ showTransactionInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></TransactionInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<SettlementInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
settlementInfo={ settlementInfo }
|
||||
isOpen={ showSettlementInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></SettlementInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<MerchantInfoSection
|
||||
merchantInfo={ merchantInfo }
|
||||
isOpen={ showMerchantInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></MerchantInfoSection>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToShowMailResend() }
|
||||
>메일 재발송</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<EmailBottomSheet
|
||||
setBottomSheetOn={ setBottomSheetOn }
|
||||
bottomSheetOn={ bottomSheetOn }
|
||||
imageSave={ false }
|
||||
sendEmail={ true }
|
||||
sendRequest={ callMailResend }
|
||||
></EmailBottomSheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user