Teren-app/resources/js/Pages/Examples/DataTableExample.vue
2025-11-20 18:11:43 +01:00

220 lines
8.2 KiB
Vue

<script setup>
import { ref } from 'vue';
import { Head } from '@inertiajs/vue3';
import AppLayout from '@/Layouts/AppLayout.vue';
import DataTableNew2 from '@/Components/DataTable/DataTableNew2.vue';
import { Badge } from '@/Components/ui/badge';
import { Button } from '@/Components/ui/button';
// Simple columns example
const simpleColumns = [
{ key: 'id', label: 'ID', sortable: true, class: 'w-20' },
{ key: 'name', label: 'Name', sortable: true },
{ key: 'email', label: 'Email', sortable: true },
{ key: 'status', label: 'Status', sortable: false },
{ key: 'amount', label: 'Amount', sortable: true, align: 'right', class: 'text-right' },
];
// Sample data
const data = ref([
{ id: 1, name: 'Alice Johnson', email: 'alice@example.com', status: 'active', amount: 1250.50 },
{ id: 2, name: 'Bob Smith', email: 'bob@example.com', status: 'inactive', amount: 890.25 },
{ id: 3, name: 'Carol Williams', email: 'carol@example.com', status: 'active', amount: 2100.00 },
{ id: 4, name: 'David Brown', email: 'david@example.com', status: 'pending', amount: 450.75 },
{ id: 5, name: 'Eve Davis', email: 'eve@example.com', status: 'active', amount: 1875.30 },
{ id: 6, name: 'Frank Miller', email: 'frank@example.com', status: 'inactive', amount: 670.00 },
{ id: 7, name: 'Grace Wilson', email: 'grace@example.com', status: 'active', amount: 3200.50 },
{ id: 8, name: 'Henry Moore', email: 'henry@example.com', status: 'pending', amount: 520.25 },
{ id: 9, name: 'Ivy Taylor', email: 'ivy@example.com', status: 'active', amount: 1950.00 },
{ id: 10, name: 'Jack Anderson', email: 'jack@example.com', status: 'inactive', amount: 780.40 },
{ id: 11, name: 'Kate Thomas', email: 'kate@example.com', status: 'active', amount: 2450.75 },
{ id: 12, name: 'Leo Jackson', email: 'leo@example.com', status: 'pending', amount: 930.60 },
]);
const selectedRows = ref([]);
function handleRowClick(row) {
console.log('Row clicked:', row);
}
function handleSelectionChange(keys) {
selectedRows.value = keys;
console.log('Selection changed:', keys);
}
function getStatusVariant(status) {
const variants = {
active: 'default',
inactive: 'secondary',
pending: 'outline',
};
return variants[status] || 'outline';
}
function formatCurrency(value) {
return new Intl.NumberFormat('sl-SI', {
style: 'currency',
currency: 'EUR',
}).format(value);
}
</script>
<template>
<AppLayout title="DataTable Example">
<Head title="DataTable Example" />
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-xl sm:rounded-lg p-6">
<div class="mb-6">
<h2 class="text-2xl font-bold text-gray-900">
DataTable Component Example
</h2>
<p class="mt-1 text-sm text-gray-600">
This is a working example of the new shadcn-vue style DataTable component
</p>
</div>
<!-- Example 1: Basic Table -->
<div class="mb-12">
<h3 class="text-lg font-semibold mb-4">Basic Table with Simple Columns</h3>
<DataTableNew2
:columns="simpleColumns"
:data="data"
filter-column="email"
filter-placeholder="Search by email..."
@row:click="handleRowClick"
>
<!-- Custom cell for status using slot -->
<template #cell-status="{ value }">
<Badge :variant="getStatusVariant(value)">
{{ value }}
</Badge>
</template>
<!-- Custom cell for amount using slot -->
<template #cell-amount="{ value }">
<span class="font-medium">{{ formatCurrency(value) }}</span>
</template>
</DataTableNew2>
</div>
<!-- Example 2: Table with Row Selection -->
<div class="mb-12">
<h3 class="text-lg font-semibold mb-4">Table with Row Selection</h3>
<div v-if="selectedRows.length" class="mb-4 p-4 bg-blue-50 rounded-lg">
<p class="text-sm font-medium text-blue-900">
Selected {{ selectedRows.length }} row(s)
</p>
</div>
<DataTableNew2
:columns="simpleColumns"
:data="data"
enable-row-selection
filter-column="name"
filter-placeholder="Search by name..."
@selection:change="handleSelectionChange"
>
<template #cell-status="{ value }">
<Badge :variant="getStatusVariant(value)">
{{ value }}
</Badge>
</template>
<template #cell-amount="{ value }">
<span class="font-medium">{{ formatCurrency(value) }}</span>
</template>
</DataTableNew2>
</div>
<!-- Example 3: Striped & Hoverable -->
<div class="mb-12">
<h3 class="text-lg font-semibold mb-4">Striped Table with Hover</h3>
<DataTableNew2
:columns="simpleColumns"
:data="data.slice(0, 5)"
:page-size="5"
striped
hoverable
>
<template #cell-status="{ value }">
<Badge :variant="getStatusVariant(value)">
{{ value }}
</Badge>
</template>
<template #cell-amount="{ value }">
<span class="font-medium">{{ formatCurrency(value) }}</span>
</template>
</DataTableNew2>
</div>
<!-- Example 4: Custom Toolbar -->
<div>
<h3 class="text-lg font-semibold mb-4">Table with Custom Toolbar Actions</h3>
<DataTableNew2
:columns="simpleColumns"
:data="data"
filter-column="email"
filter-placeholder="Search emails..."
>
<!-- Add custom buttons to toolbar -->
<template #toolbar-actions="{ table }">
<Button variant="outline" size="sm" @click="() => console.log('Export clicked')">
Export
</Button>
<Button variant="default" size="sm" @click="() => console.log('Add clicked')">
Add New
</Button>
</template>
<template #cell-status="{ value }">
<Badge :variant="getStatusVariant(value)">
{{ value }}
</Badge>
</template>
<template #cell-amount="{ value }">
<span class="font-medium">{{ formatCurrency(value) }}</span>
</template>
</DataTableNew2>
</div>
<!-- Example 5: Full Custom Toolbar -->
<div class="mt-12">
<h3 class="text-lg font-semibold mb-4">Table with Custom Filters in Toolbar</h3>
<DataTableNew2
:columns="simpleColumns"
:data="data"
filter-column="name"
filter-placeholder="Search names..."
>
<!-- Add custom filter controls -->
<template #toolbar-filters="{ table }">
<select
class="h-8 rounded-md border border-input bg-background px-3 py-1 text-sm"
@change="(e) => {
const column = table.getColumn('status');
column?.setFilterValue(e.target.value || undefined);
}"
>
<option value="">All Status</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
<option value="pending">Pending</option>
</select>
</template>
<template #cell-status="{ value }">
<Badge :variant="getStatusVariant(value)">
{{ value }}
</Badge>
</template>
<template #cell-amount="{ value }">
<span class="font-medium">{{ formatCurrency(value) }}</span>
</template>
</DataTableNew2>
</div>
</div>
</div>
</div>
</AppLayout>
</template>