fix: style

This commit is contained in:
2026-04-07 13:54:08 +02:00
parent b0d0338d23
commit a290a72d1d

View File

@@ -10,8 +10,11 @@
<script setup lang="ts"> <script setup lang="ts">
import Default from '@/layouts/default.vue'; import Default from '@/layouts/default.vue';
import { onMounted, ref} from 'vue' import { computed, onMounted, ref, resolveComponent, h } from 'vue'
import { useFetchJson } from '@/composable/useFetchJson'; import { useFetchJson } from '@/composable/useFetchJson';
import type { TableColumn } from '@nuxt/ui';
import type { Product } from '@/types/product';
import { useRoute, useRouter } from 'vue-router';
const usersList = ref([]) const usersList = ref([])
const error = ref() const error = ref()
@@ -36,4 +39,227 @@ async function fetchUsersList() {
onMounted(() => { onMounted(() => {
fetchUsersList() fetchUsersList()
}) })
const router = useRouter()
const route = useRoute()
const sortField = computed({
get: () => [
route.query.sort as string | undefined,
route.query.direction as 'asc' | 'desc' | undefined
],
set: ([sort]: [string, 'asc' | 'desc']) => {
const currentSort = route.query.sort as string | undefined
const currentDirection = route.query.direction as 'asc' | 'desc' | undefined
let query = { ...route.query }
if (currentSort === sort) {
if (currentDirection === 'asc') {
query.direction = 'desc'
} else if (currentDirection === 'desc') {
delete query.sort
delete query.direction
} else {
query.direction = 'asc'
query.sort = sort
}
} else {
query.sort = sort
query.direction = 'asc'
}
router.push({ query })
}
})
function getIcon(name: string) {
if (sortField.value[0] === name) {
if (sortField.value[1] === 'asc') return 'i-lucide-arrow-up-narrow-wide'
if (sortField.value[1] === 'desc') return 'i-lucide-arrow-down-wide-narrow'
}
return 'i-lucide-arrow-up-down'
}
const UInputNumber = resolveComponent('UInputNumber')
const UInput = resolveComponent('UInput')
const UButton = resolveComponent('UButton')
const UIcon = resolveComponent('UIcon')
const updateFilter = debounce((columnId: string, val: string) => {
const newFilters = { ...filters.value }
if (val) newFilters[columnId] = val
else delete newFilters[columnId]
filters.value = newFilters
}, 400)
const filters = computed<Record<string, string>>({
get: () => {
const q = { ...route.query }
delete q.page
delete q.sort
delete q.direction
return q as Record<string, string>
},
set: (val) => {
const baseQuery = { ...route.query }
Object.keys(baseQuery).forEach(key => {
if (!['page', 'sort', 'direction'].includes(key)) {
delete baseQuery[key]
}
})
router.push({
query: {
...baseQuery,
...val,
page: 1
}
})
}
})
import errorImg from '@/assets/error.svg'
import { debounce } from 'chart.js/helpers';
const columns: TableColumn<Product>[] = [
{
accessorKey: 'user_id',
header: ({ column }) => {
return h('div', { class: 'flex flex-col gap-1' }, [
h('div', {
class: 'flex items-center gap-2 cursor-pointer',
onClick: () => {
sortField.value = ['user_id', 'asc']
}
}, [
h('span', 'Client ID'),
h(UIcon, {
name: getIcon('user_id')
})
]),
])
},
// header: '#',
cell: ({ row }) => `#${row.getValue('user_id') as number}`
},
// {
// accessorKey: 'image_link',
// header: 'Image',
// cell: ({ row }) => {
// return h('img', {
// src: row.getValue('image_link') as string,
// style: 'width:40px;height:40px;object-fit:cover;',
// onError: (e: Event) => {
// const target = e.target as HTMLImageElement
// target.src = errorImg
// }
// })
// },
// },
{
accessorKey: 'company_name',
header: ({ column }) => {
return h('div', { class: 'flex flex-col gap-1' }, [
h('div', {
class: 'flex items-center gap-2 cursor-pointer',
onClick: () => {
sortField.value = ['company_name', 'asc']
}
}, [
h('span', 'Company Name'),
h(UIcon, {
name: getIcon('name')
})
]),
h(UInput, {
placeholder: 'Search...',
modelValue: filters.value[column.id] ?? '',
'onUpdate:modelValue': (val: string) => {
updateFilter(column.id, val)
},
size: 'xs'
})
])
},
cell: ({ row }) => row.getValue('company_name') as string,
filterFn: (row, columnId, value) => {
const name = row.getValue(columnId) as string
return name.toLowerCase().includes(value.toLowerCase())
}
},
{
accessorKey: 'name',
header: ({ column }) => {
return h('div', { class: 'flex flex-col gap-1' }, [
h('div', {
class: 'flex items-center gap-2 cursor-pointer',
onClick: () => {
sortField.value = ['name', 'asc']
}
}, [
h('span', 'Name/Surname'),
h(UIcon, {
name: getIcon('quantity')
})
]),
h(UInput, {
placeholder: 'Search...',
modelValue: filters.value[column.id] ?? '',
'onUpdate:modelValue': (val: string) => {
updateFilter(column.id, val)
},
size: 'xs'
})
])
},
cell: ({ row }) => row.getValue('name') as string
},
{
accessorKey: 'email',
header: ({ column }) => {
return h('div', { class: 'flex flex-col gap-1' }, [
h('div', {
class: 'flex items-center gap-2 cursor-pointer',
onClick: () => {
sortField.value = ['email', 'asc']
}
}, [
h('span', 'Email'),
h(UIcon, {
name: getIcon('quantity')
})
]),
h(UInput, {
placeholder: 'Search...',
modelValue: filters.value[column.id] ?? '',
'onUpdate:modelValue': (val: string) => {
updateFilter(column.id, val)
},
size: 'xs'
})
])
},
cell: ({ row }) => row.getValue('email') as string
},
// {
// accessorKey: 'count',
// header: '',
// cell: ({ row }) => {
// return h(UButton, {
// onClick: () => {
// goToProduct(row.original.product_id, row.original.link_rewrite)
// },
// class: 'cursor-pointer',
// color: 'info',
// variant: 'soft'
// }, () => 'Show product')
// },
// }
]
</script> </script>