diff --git a/components/Table.vue b/components/Table.vue
deleted file mode 100644
index 57e1bb4..0000000
--- a/components/Table.vue
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
diff --git a/components/UiTable.vue b/components/UiTable.vue
new file mode 100644
index 0000000..dc46697
--- /dev/null
+++ b/components/UiTable.vue
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+ |
+
+
+ {{ { asc: ' 🔼', desc: ' 🔽' }[header.column.getIsSorted() as string] }}
+ |
+
+
+
+
+
+ |
+
+ |
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/index.vue b/pages/index.vue
index e0a9538..632d9cb 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -11,68 +11,7 @@
/>
-
-
-
-
-
- |
-
-
- {{ { asc: ' 🔼', desc: ' 🔽' }[header.column.getIsSorted() as string] }}
- |
-
-
-
-
-
- |
-
- |
-
-
-
-
-
+
@@ -94,14 +33,10 @@
import { UTooltip } from '#components'
import {
createColumnHelper,
- FlexRender,
- getCoreRowModel,
- getSortedRowModel,
- useVueTable,
} from '@tanstack/vue-table'
-import { useVirtualizer } from '@tanstack/vue-virtual'
import { useDebounceFn, useMediaQuery } from '@vueuse/core'
import { useGetPosts, useGetUsers } from '~/api/queries'
+import UiTable from '~/components/UiTable.vue'
const isMobile = useMediaQuery('(max-width: 1280px)')
const open = ref(false)
@@ -113,14 +48,13 @@ const updateSearch = useDebounceFn((value: string) => {
const { data: posts, isLoading: postsIsLoading } = useGetPosts(search)
const { data: users, isLoading: usersIsLoading } = useGetUsers()
-const tableData = computed(() =>
- posts?.value?.map(post => ({
- userId: post?.userId,
- userEmail: users?.value?.find(user => user?.id === post?.userId)?.email,
- id: post?.id,
- title: post?.title,
- body: post?.body,
- })))
+const tableData = computed(() => (posts?.value ?? []).map(post => ({
+ userId: post?.userId,
+ userEmail: users?.value?.find(user => user?.id === post?.userId)?.email,
+ id: post?.id,
+ title: post?.title,
+ body: post?.body,
+})))
const columnHelper = createColumnHelper()
const columns = [
@@ -178,42 +112,6 @@ const columns = [
}),
]
-const table = useVueTable({
- get data() {
- return tableData
- },
- columns,
- getCoreRowModel: getCoreRowModel(),
- getSortedRowModel: getSortedRowModel(),
-})
-
-const rows = computed(() => table?.getRowModel()?.rows)
-const tableContainerRef = ref(null)
-
-const rowVirtualizerOptions = computed(() => {
- return {
- count: rows.value.length,
- estimateSize: () => 50,
- getScrollElement: () => tableContainerRef.value,
- overscan: 5,
- }
-})
-
-const rowVirtualizer = useVirtualizer(rowVirtualizerOptions)
-
-const virtualRows = computed(() => rowVirtualizer.value.getVirtualItems())
-const totalSize = computed(() => rowVirtualizer.value.getTotalSize())
-
-function measureElement(el?: Element) {
- if (!el) {
- return
- }
-
- rowVirtualizer.value.measureElement(el)
-
- return undefined
-}
-
function openPost(post: Post) {
selectedUser.value = users?.value?.find(user => user?.id === post?.userId)
open.value = true
@@ -251,91 +149,6 @@ function truncate(text: string, max = 15) {
}
}
-/* -------------------- TABLE WRAPPER -------------------- */
-.table-wrapper {
- position: relative;
- margin-top: calc(40px + 10px);
- border-radius: 14px;
- overflow-y: auto;
- height: 600px;
- scrollbar-width: thin;
-
- @include mobile {
- height: 500px;
- }
-}
-
-table {
- min-width: 100%;
- border-collapse: separate;
- border-spacing: 0;
-
- background: var(--ui-bg-elevated);
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
- white-space: nowrap;
-}
-
-/* -------------------- HEADER -------------------- */
-
-thead {
- display: grid;
- position: sticky;
- top: 0;
- z-index: 1;
-}
-
-thead tr {
- display: flex;
- width: 100%;
-}
-
-thead th {
- background: var(--ui-bg-accented);
- color: var(--ui-text);
- padding: 12px 14px;
-
- border-bottom: 1px solid var(--ui-border);
- user-select: none;
-
- transition: background 0.15s ease;
-}
-
-thead th:hover {
- cursor: pointer;
-}
-
-/* -------------------- BODY -------------------- */
-
-tbody {
- display: grid;
- position: relative;
-}
-
-tbody tr {
- display: flex;
- position: absolute;
- width: 100%;
- height: 50px;
- transition: background 0.2s ease;
-}
-
-tbody tr:nth-child(odd) {
- background: var(--ui-bg-subtle);
-}
-
-tbody tr:hover {
- background: var(--ui-bg-accented);
-}
-
-tbody td {
- padding: 10px 12px;
- border-bottom: 1px solid var(--ui-border-subtle);
-}
-
-tbody tr:last-child td {
- border-bottom: none;
-}
-
/* -------------------- CLICKABLE USER EMAIL CELL -------------------- */
.title-cell {