feat: add withdraw request functionality and UI components
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { usePage } from '@inertiajs/inertia-vue3';
|
||||
import { toast } from 'vue3-toastify';
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue';
|
||||
import TableGeneric from '../../../components/ui/TableGeneric.vue';
|
||||
import UiCard from '../../../components/ui/UiCard.vue';
|
||||
import UiInput from '../../../components/ui/UiInput.vue';
|
||||
import UiButton from '../../../components/ui/UiButton.vue';
|
||||
import WalletSvg from '../../../components/svg/wallet.svg';
|
||||
import WithdrawRequestCard from '../../../components/dashboard/wallet/WithdrawRequestCard.vue';
|
||||
import { walletTransactionColumns } from '../../../data/walletTransactionsTableColumns';
|
||||
import { withdrawRequestColumns } from '../../../data/withdrawRequestsTableColumns';
|
||||
import { convertEnglishToPersian, convertPersianToEnglish, formatPrice } from '../../../utils/numberUtils';
|
||||
|
||||
const props = defineProps({
|
||||
transactions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
withdrawRequests: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
bankCards: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const { props: pageProps } = usePage();
|
||||
|
||||
const quickAmounts = [100000, 200000, 500000];
|
||||
|
||||
const amount = ref('');
|
||||
const depositing = ref(false);
|
||||
|
||||
const numericAmount = computed(() => Number(convertPersianToEnglish(amount.value).replace(/\D/g, '')) || 0);
|
||||
|
||||
const formattedBalance = computed(() => formatPrice(pageProps.value.auth?.wallet_balance || 0));
|
||||
|
||||
const pendingWithdrawAmount = computed(() => props.withdrawRequests
|
||||
.filter((request) => request.status === 'در انتظار بررسی')
|
||||
.reduce((sum, request) => sum + request.amount, 0));
|
||||
|
||||
const withdrawStatusClasses = (status) => {
|
||||
if (status === 'تایید شده') {
|
||||
return 'text-[#1F7A4D] bg-[#E6F4EC]';
|
||||
}
|
||||
|
||||
if (status === 'رد شده') {
|
||||
return 'text-[#7A1419] bg-[#F8E9EA]';
|
||||
}
|
||||
|
||||
return 'text-[#576989] bg-[#EEF2F8]';
|
||||
};
|
||||
|
||||
const formatCardNumber = (cardNumber) => convertEnglishToPersian(cardNumber.replace(/(\d{4})(?=\d)/g, '$1 - '));
|
||||
|
||||
const selectQuickAmount = (value) => {
|
||||
amount.value = String(value);
|
||||
};
|
||||
|
||||
const handleDeposit = async () => {
|
||||
if (numericAmount.value < 10000) {
|
||||
toast.error('حداقل مبلغ شارژ ۱۰٬۰۰۰ تومان است.');
|
||||
return;
|
||||
}
|
||||
|
||||
depositing.value = true;
|
||||
try {
|
||||
const { data } = await window.axios.post('/dashboard/wallet/deposit', { amount: numericAmount.value });
|
||||
window.location.href = data.url;
|
||||
} catch (error) {
|
||||
depositing.value = false;
|
||||
toast.error(error.response?.data?.message || 'خطا در اتصال به درگاه پرداخت. لطفا دوباره تلاش کنید.');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<div class="flex flex-col gap-4">
|
||||
<UiCard title="کیف پول" variant="default">
|
||||
<div class="grid grid-cols-2 max-sm:grid-cols-1 gap-4">
|
||||
<div class="flex items-center gap-3 bg-[#EEF2F8] border border-[#DEE3EB] rounded-[12px] px-5 py-4">
|
||||
<WalletSvg class="w-6 h-6" />
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="text-[11px] font-normal text-[#576989]">موجودی کیف پول</span>
|
||||
<strong class="text-[16px] font-bold text-[#3E4C63]">{{ formattedBalance }} تومان</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 bg-[#F8FAFC] border border-[#DEE3EB] rounded-[12px] px-5 py-4">
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="text-[11px] font-normal text-[#576989]">مبلغ در انتظار برداشت</span>
|
||||
<strong class="text-[16px] font-bold text-[#3E4C63]">{{ formatPrice(pendingWithdrawAmount) }} تومان</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</UiCard>
|
||||
|
||||
<UiCard title="شارژ کیف پول" variant="default">
|
||||
<form class="flex flex-col gap-4" @submit.prevent="handleDeposit">
|
||||
<p class="text-[11px] font-normal text-[#576989] leading-6">
|
||||
مبلغ مورد نظر را وارد کنید؛ پس از پرداخت از طریق درگاه بانکی، موجودی کیف پول شما بلافاصله افزایش مییابد.
|
||||
</p>
|
||||
<div class="flex items-end gap-3 max-sm:flex-col max-sm:items-stretch">
|
||||
<UiInput
|
||||
v-model="amount"
|
||||
label="مبلغ شارژ"
|
||||
placeholder="مبلغ مورد نظر را به تومان وارد کنید"
|
||||
prefixEnd="تومان"
|
||||
prefixClasses="!border-dominant-50"
|
||||
class="!w-[22rem] max-sm:!w-full"
|
||||
customClass="!border-dominant-50 !font-normal !text-[12px]"
|
||||
/>
|
||||
<UiButton
|
||||
label="افزایش موجودی"
|
||||
severity="success"
|
||||
size="small"
|
||||
:loading="depositing"
|
||||
:disabled="depositing"
|
||||
@click="handleDeposit"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<button
|
||||
v-for="value in quickAmounts"
|
||||
:key="value"
|
||||
type="button"
|
||||
class="text-[11px] font-normal text-[#576989] bg-[#F5F7FA] border border-[#DEE3EB] rounded-lg px-3 py-1.5 hover:bg-[#EEF2F8]"
|
||||
@click="selectQuickAmount(value)"
|
||||
>
|
||||
{{ formatPrice(value) }} تومان
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</UiCard>
|
||||
|
||||
<WithdrawRequestCard :bank-cards="bankCards" />
|
||||
|
||||
<UiCard title="درخواستهای برداشت" variant="default">
|
||||
<TableGeneric
|
||||
class="bg-white !rounded-2xl"
|
||||
:data="withdrawRequests"
|
||||
customStyle="!text-[11px] !font-normal"
|
||||
:searchable="false"
|
||||
:columns="withdrawRequestColumns"
|
||||
:selectable="false"
|
||||
:pagination="null"
|
||||
:model-value="[]"
|
||||
>
|
||||
<template #column-bank_card="{ data }">
|
||||
<span v-if="data.bank_card" dir="ltr">{{ formatCardNumber(data.bank_card.card_number) }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
<template #column-status="{ data }">
|
||||
<span class="text-[11px] font-normal rounded-md px-2 py-1" :class="withdrawStatusClasses(data.status)">
|
||||
{{ data.status }}
|
||||
</span>
|
||||
</template>
|
||||
</TableGeneric>
|
||||
</UiCard>
|
||||
|
||||
<UiCard title="تراکنشها" variant="default">
|
||||
<TableGeneric
|
||||
class="bg-white !rounded-2xl"
|
||||
:data="transactions.data"
|
||||
customStyle="!text-[11px] !font-normal"
|
||||
:searchable="false"
|
||||
:columns="walletTransactionColumns"
|
||||
:selectable="false"
|
||||
:pagination="transactions.meta"
|
||||
:model-value="[]"
|
||||
>
|
||||
<template #column-type="{ data }">
|
||||
<span
|
||||
class="text-[11px] font-normal rounded-md px-2 py-1"
|
||||
:class="data.type === 'واریز' ? 'text-[#1F7A4D] bg-[#E6F4EC]' : 'text-[#7A1419] bg-[#F8E9EA]'"
|
||||
>
|
||||
{{ data.type }}
|
||||
</span>
|
||||
</template>
|
||||
</TableGeneric>
|
||||
</UiCard>
|
||||
</div>
|
||||
</ClientLayout>
|
||||
</template>
|
||||
Reference in New Issue
Block a user