1+ <script setup lang="ts">
2+ import { DataTable , type ColumnDef } from ' @/components/ui/data-table' ;
3+ import { ref , h } from ' vue' ;
4+ import type { JobData } from ' @/lib/types' ;
5+ import { Checkbox } from ' @/components/ui/checkbox' ;
6+ import DataTableHeader from ' @/components/ui/data-table/DataTableHeader.vue' ;
7+ import type { Column } from ' @tanstack/vue-table' ;
8+ import { Badge } from ' @/components/ui/badge' ;
9+
10+ const props = defineProps <{
11+ jobs: JobData []
12+ }>();
13+
14+ const emit = defineEmits <{
15+ (e : ' selection-change' , selectedJobs : any ): void
16+ }>();
17+
18+ interface IData {
19+ id: string
20+
21+ title: string
22+ company: string
23+ status: string
24+ }
25+
26+ const statusVariants: Record <string , string > = {
27+ applied: ' info' , // Blue — represents action taken
28+ saved: ' secondary' , // Gray — neutral, passive state
29+ rejected: ' danger' , // Red — error or negative outcome
30+ interviewed: ' warning' , // Yellow/Amber — pending or in-progress stage
31+ };
32+
33+ const columns: ColumnDef <IData >[] = [
34+ {
35+ accessorKey: ' id' ,
36+ header : ({ table }) => h (Checkbox , {
37+ checked: table .getIsAllPageRowsSelected (),
38+ ' onUpdate:checked' : val => {
39+ table .toggleAllPageRowsSelected (!! val );
40+ emit (' selection-change' , table .getSelectedRowModel ().flatRows .map (row => row .original ));
41+ },
42+ ariaLabel: ' Select All' ,
43+ class: ' translate-y-0.5' ,
44+ }),
45+ cell : ({ table , row }) => h (Checkbox , {
46+ checked: row .getIsSelected (),
47+ ' onUpdate:checked' : val => {
48+ row .toggleSelected (!! val );
49+ emit (' selection-change' , table .getSelectedRowModel ().flatRows .map (row => row .original ));
50+ },
51+ ' ariaLabel' : ' Select row' ,
52+ class: ' translate-y-0.5' ,
53+ enableSorting: false ,
54+ enableHiding: false ,
55+ })
56+ },
57+ {
58+ accessorKey: ' id' ,
59+ header: ' ID' ,
60+ enableSorting: false ,
61+ },
62+ {
63+ accessorKey: ' title' ,
64+ header : ({ column }) => h (DataTableHeader , {
65+ column: column as Column <IData >,
66+ title: ' Job Title' ,
67+ ' onUpdate:sort' : (val ) => {
68+ console .log (val )
69+ },
70+ })
71+ },
72+ {
73+ accessorKey: ' company' ,
74+ header: ' Company' ,
75+ enableSorting: false ,
76+ },
77+ {
78+ accessorKey: ' status' ,
79+ header: ' Status' ,
80+ cell : ({ row }) => h (' div' , {
81+ class: ' max-w-[500px] truncate flex items-center' ,
82+ }, [
83+ h (Badge , {
84+ variant: (statusVariants [row .original .status ] as any ),
85+ class: ' mr-2' ,
86+ }, () => row .original .status ),
87+ ]),
88+ enableSorting: false ,
89+ },
90+ {
91+ id: ' actions' ,
92+ },
93+ ];
94+
95+ function transformAsList(jobs : JobData []) {
96+ return jobs .map (job => ({
97+ id: job .job_id ,
98+ title: job .job_title .split (' :' )[1 ].trim (),
99+ company: job .company ,
100+ status: job .status
101+ }));
102+ }
103+
104+ </script >
105+
106+ <template >
107+ <div >
108+ <DataTable :columns =" columns" :data =" transformAsList(jobs)" ></DataTable >
109+ </div >
110+ </template >
0 commit comments