mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 12:14:41 +01:00
122 lines
3.0 KiB
Vue
122 lines
3.0 KiB
Vue
<script setup lang="ts">
|
|
import { h, resolveComponent } from 'vue'
|
|
import type { TableColumn } from '@nuxt/ui'
|
|
|
|
const UCheckbox = resolveComponent('UCheckbox')
|
|
const UBadge = resolveComponent('UBadge')
|
|
|
|
type Payment = {
|
|
id: string
|
|
date: string
|
|
status: 'paid' | 'failed' | 'refunded'
|
|
email: string
|
|
amount: number
|
|
}
|
|
|
|
const data = ref<Payment[]>([{
|
|
id: '4600',
|
|
date: '2024-03-11T15:30:00',
|
|
status: 'paid',
|
|
email: 'james.anderson@example.com',
|
|
amount: 594
|
|
}, {
|
|
id: '4599',
|
|
date: '2024-03-11T10:10:00',
|
|
status: 'failed',
|
|
email: 'mia.white@example.com',
|
|
amount: 276
|
|
}, {
|
|
id: '4598',
|
|
date: '2024-03-11T08:50:00',
|
|
status: 'refunded',
|
|
email: 'william.brown@example.com',
|
|
amount: 315
|
|
}, {
|
|
id: '4597',
|
|
date: '2024-03-10T19:45:00',
|
|
status: 'paid',
|
|
email: 'emma.davis@example.com',
|
|
amount: 529
|
|
}, {
|
|
id: '4596',
|
|
date: '2024-03-10T15:55:00',
|
|
status: 'paid',
|
|
email: 'ethan.harris@example.com',
|
|
amount: 639
|
|
}])
|
|
|
|
const columns: TableColumn<Payment>[] = [{
|
|
id: 'select',
|
|
header: ({ table }) => h(UCheckbox, {
|
|
'modelValue': table.getIsSomePageRowsSelected() ? 'indeterminate' : table.getIsAllPageRowsSelected(),
|
|
'onUpdate:modelValue': (value: boolean | 'indeterminate') => table.toggleAllPageRowsSelected(!!value),
|
|
'aria-label': 'Select all'
|
|
}),
|
|
cell: ({ row }) => h(UCheckbox, {
|
|
'modelValue': row.getIsSelected(),
|
|
'onUpdate:modelValue': (value: boolean | 'indeterminate') => row.toggleSelected(!!value),
|
|
'aria-label': 'Select row'
|
|
})
|
|
}, {
|
|
accessorKey: 'date',
|
|
header: 'Date',
|
|
cell: ({ row }) => {
|
|
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
|
day: 'numeric',
|
|
month: 'short',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
hour12: false
|
|
})
|
|
}
|
|
}, {
|
|
accessorKey: 'status',
|
|
header: 'Status',
|
|
cell: ({ row }) => {
|
|
const color = ({
|
|
paid: 'success' as const,
|
|
failed: 'error' as const,
|
|
refunded: 'neutral' as const
|
|
})[row.getValue('status') as string]
|
|
|
|
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
|
}
|
|
}, {
|
|
accessorKey: 'email',
|
|
header: 'Email'
|
|
}, {
|
|
accessorKey: 'amount',
|
|
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
|
cell: ({ row }) => {
|
|
const amount = Number.parseFloat(row.getValue('amount'))
|
|
|
|
const formatted = new Intl.NumberFormat('en-US', {
|
|
style: 'currency',
|
|
currency: 'EUR'
|
|
}).format(amount)
|
|
|
|
return h('div', { class: 'text-right font-medium' }, formatted)
|
|
}
|
|
}]
|
|
|
|
const table = useTemplateRef('table')
|
|
|
|
const rowSelection = ref({ 1: true })
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex-1 w-full">
|
|
<UTable
|
|
ref="table"
|
|
v-model:row-selection="rowSelection"
|
|
:data="data"
|
|
:columns="columns"
|
|
/>
|
|
|
|
<div class="px-4 py-3.5 border-t border-accented text-sm text-muted">
|
|
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
|
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
|
</div>
|
|
</div>
|
|
</template>
|