111 lines
4.2 KiB
Vue
111 lines
4.2 KiB
Vue
<template>
|
|
<div class="flex flex-col h-full">
|
|
<LayoutHeader :title="$t('payments.customers')">
|
|
<template #right>
|
|
<TextInput
|
|
v-model="searchQuery"
|
|
type="text"
|
|
:placeholder="$t('common.search')"
|
|
class="w-64"
|
|
>
|
|
<template #prefix>
|
|
<FeatherIcon name="search" class="h-4 w-4 text-ink-gray-4" />
|
|
</template>
|
|
</TextInput>
|
|
<Button variant="subtle" @click="exportCustomers">
|
|
<template #prefix>
|
|
<FeatherIcon name="download" class="h-4 w-4" />
|
|
</template>
|
|
{{ $t('common.export') }}
|
|
</Button>
|
|
</template>
|
|
</LayoutHeader>
|
|
|
|
<div class="flex-1 overflow-auto p-5">
|
|
<div class="rounded-lg border overflow-hidden">
|
|
<table class="min-w-full divide-y">
|
|
<thead class="bg-surface-gray-2">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-ink-gray-5 uppercase">{{ $t('payments.customer.name') }}</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-ink-gray-5 uppercase">{{ $t('payments.customer.email') }}</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-ink-gray-5 uppercase">{{ $t('payments.connections') }}</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-ink-gray-5 uppercase">{{ $t('payments.customer.amount') }}</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-ink-gray-5 uppercase">{{ $t('payments.customer.status') }}</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-ink-gray-5 uppercase">Since</th>
|
|
<th class="px-6 py-3 text-right text-xs font-medium text-ink-gray-5 uppercase">{{ $t('common.actions') }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y">
|
|
<tr v-for="customer in filteredCustomers" :key="customer.id">
|
|
<td class="px-6 py-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="w-8 h-8 rounded-full bg-surface-gray-2 flex items-center justify-center">
|
|
<span class="text-sm font-medium text-ink-gray-5">
|
|
{{ customer.name.charAt(0) }}
|
|
</span>
|
|
</div>
|
|
<span class="text-sm font-medium text-ink-gray-9">{{ customer.name }}</span>
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-ink-gray-7">{{ customer.email }}</td>
|
|
<td class="px-6 py-4 text-sm text-ink-gray-7">{{ customer.connections }}</td>
|
|
<td class="px-6 py-4 text-sm font-medium text-ink-gray-9">
|
|
{{ formatCurrency(customer.monthlyAmount) }}/mo
|
|
</td>
|
|
<td class="px-6 py-4">
|
|
<Badge
|
|
:variant="customer.status === 'active' ? 'success' : 'info'"
|
|
:label="customer.status"
|
|
/>
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-ink-gray-7">{{ customer.since }}</td>
|
|
<td class="px-6 py-4 text-right">
|
|
<Button variant="ghost" size="sm" @click="viewCustomer(customer)">
|
|
<FeatherIcon name="eye" class="h-4 w-4" />
|
|
</Button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from 'vue'
|
|
import { Button, Badge, TextInput, FeatherIcon } from 'frappe-ui'
|
|
import LayoutHeader from '@/components/Common/LayoutHeader.vue'
|
|
import { customers as mockCustomers } from '@/mocks/payments'
|
|
|
|
const searchQuery = ref('')
|
|
const customers = ref(mockCustomers)
|
|
|
|
const filteredCustomers = computed(() => {
|
|
if (!searchQuery.value) return customers.value
|
|
|
|
const query = searchQuery.value.toLowerCase()
|
|
return customers.value.filter(
|
|
c =>
|
|
c.name.toLowerCase().includes(query) ||
|
|
c.email.toLowerCase().includes(query)
|
|
)
|
|
})
|
|
|
|
function formatCurrency(value) {
|
|
return new Intl.NumberFormat('ru-RU', {
|
|
style: 'currency',
|
|
currency: 'RUB',
|
|
minimumFractionDigits: 0,
|
|
}).format(value)
|
|
}
|
|
|
|
function exportCustomers() {
|
|
console.log('Exporting customers...')
|
|
}
|
|
|
|
function viewCustomer(customer) {
|
|
console.log('Viewing customer:', customer.name)
|
|
}
|
|
</script>
|