Files
boursecu_admin/src/pages/menuPages/customers/base/components/WalletChargeModalBody.vue
T

174 lines
4.6 KiB
Vue

<template>
<div class="wallet-charge-modal-body">
<div v-if="showCustomerSelect" class="wallet-charge-modal-body__section">
<label class="wallet-charge-modal-body__label">مشتری</label>
<a-select
v-model:value="customerIdProxy"
show-search
allow-clear
placeholder="انتخاب کنید"
class="w-full"
size="middle"
:options="customerOptions"
:loading="customersLoading"
:filter-option="filterCustomer"
/>
</div>
<div v-if="resolvedCustomerId && !targetsLoading" class="wallet-charge-modal-body__assets">
<CustomerWalletBalancePanel
:customer-id="resolvedCustomerId"
:charge-targets="targets"
:selected-charge-key="selectedTargetKey"
compact
@select-charge-target="selectedTargetKeyProxy = $event"
/>
</div>
<div class="wallet-charge-modal-body__section">
<label class="wallet-charge-modal-body__label">محصول / کیف پول</label>
<a-spin :spinning="targetsLoading">
<a-select
v-model:value="selectedTargetKeyProxy"
show-search
class="w-full"
:options="targetOptions"
placeholder="انتخاب کنید"
:filter-option="filterTarget"
/>
</a-spin>
</div>
<WalletChargeForm
ref="formRef"
:model-value="formCharge"
:unit-label="selectedTarget?.unit ?? 'ریال'"
:is-money="selectedTarget?.kind === 'money'"
:wallet-label="selectedTarget?.label"
/>
</div>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import WalletChargeForm from '@/pages/menuPages/customers/base/components/WalletChargeForm.vue'
import CustomerWalletBalancePanel from '@/components/customer/CustomerWalletBalancePanel.vue'
import { getCustomersList } from '@/api/customer'
import type { Charge, ChargeTarget } from '@/model/wallet'
import type { Customer } from '@/model/customer'
const props = defineProps<{
formCharge: Charge
selectedTargetKey: string
customerId?: number | null
showCustomerSelect?: boolean
targets: ChargeTarget[]
targetsLoading?: boolean
selectedTarget?: ChargeTarget
}>()
const emit = defineEmits<{
(e: 'update:formCharge', value: Charge): void
(e: 'update:selectedTargetKey', value: string): void
}>()
const formRef = ref<InstanceType<typeof WalletChargeForm>>()
const customers = ref<Customer[]>([])
const customersLoading = ref(false)
const formCharge = computed({
get: () => props.formCharge,
set: (value: Charge) => emit('update:formCharge', value),
})
const selectedTargetKeyProxy = computed({
get: () => props.selectedTargetKey,
set: (value: string) => emit('update:selectedTargetKey', value),
})
const resolvedCustomerId = computed(
() => props.formCharge.customer_id ?? props.customerId ?? undefined,
)
const customerIdProxy = computed({
get: () => formCharge.value.customer_id ?? undefined,
set: (value: number | undefined) => {
emit('update:formCharge', { ...formCharge.value, customer_id: value })
},
})
const customerOptions = computed(() =>
customers.value.map((customer) => ({
value: customer.id,
label: `${customer.name ?? ''} — ${customer.mobile ?? ''}`.trim(),
})),
)
const targetOptions = computed(() =>
props.targets.map((target) => ({
value: target.key,
label: target.label,
})),
)
function filterCustomer(input: string, option?: { label?: string }) {
return String(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
function filterTarget(input: string, option?: { label?: string }) {
return String(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
async function loadCustomers() {
if (!props.showCustomerSelect) return
customersLoading.value = true
try {
customers.value = (await getCustomersList()) ?? []
} catch (e) {
console.error(e)
} finally {
customersLoading.value = false
}
}
watch(
() => props.showCustomerSelect,
(show) => {
if (show) void loadCustomers()
},
{ immediate: true },
)
defineExpose({
validateFields: () => formRef.value?.validateFields?.(),
})
</script>
<style scoped>
.wallet-charge-modal-body {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0 0.75rem 0.25rem;
}
.wallet-charge-modal-body__assets {
margin-bottom: 0.75rem;
width: 100%;
min-width: 0;
max-width: 100%;
}
.wallet-charge-modal-body__section {
display: flex;
flex-direction: column;
gap: 0.35rem;
}
.wallet-charge-modal-body__label {
font-size: 0.75rem;
font-weight: 600;
color: var(--admin-text-secondary, #64748b);
}
</style>