@@ -6,14 +6,34 @@ import Link from "next/link";
66import { useState } from "react" ;
77import type { Team } from "@/api/team" ;
88import { Badge } from "@/components/ui/badge" ;
9- import { useDashboardRouter } from "@/lib/DashboardRouter" ;
9+ import {
10+ Table ,
11+ TableBody ,
12+ TableCell ,
13+ TableContainer ,
14+ TableHead ,
15+ TableHeader ,
16+ TableRow ,
17+ } from "@/components/ui/table" ;
1018import type { SupportTicketListItem } from "../types/tickets" ;
1119import {
1220 getTicketStatusBadgeVariant ,
1321 getTicketStatusLabel ,
1422} from "../utils/ticket-status" ;
1523import { SupportCaseFilters } from "./case-filters" ;
1624
25+ function isTicketOpen ( ticket : SupportTicketListItem ) {
26+ return (
27+ ticket . status === "in_progress" ||
28+ ticket . status === "needs_response" ||
29+ ticket . status === "on_hold"
30+ ) ;
31+ }
32+
33+ function isTicketClosed ( ticket : SupportTicketListItem ) {
34+ return ticket . status === "resolved" || ticket . status === "closed" ;
35+ }
36+
1737export function SupportsCaseList ( {
1838 tickets,
1939 team,
@@ -23,21 +43,17 @@ export function SupportsCaseList({
2343} ) {
2444 const [ activeTab , setActiveTab ] = useState ( "all" ) ;
2545 const [ searchQuery , setSearchQuery ] = useState ( "" ) ;
26- const router = useDashboardRouter ( ) ;
2746
2847 // Filter tickets based on active tab and search query
2948 const filteredTickets = tickets . filter ( ( ticket ) => {
3049 // Filter by tab
3150 let matchesTab = true ;
3251 switch ( activeTab ) {
3352 case "open" :
34- matchesTab =
35- ( ticket . status as string ) === "in_progress" ||
36- ( ticket . status as string ) === "needs_response" ||
37- ( ticket . status as string ) === "on_hold" ;
53+ matchesTab = isTicketOpen ( ticket ) ;
3854 break ;
3955 case "closed" :
40- matchesTab = ticket . status === "resolved" || ticket . status === "closed" ;
56+ matchesTab = isTicketClosed ( ticket ) ;
4157 break ;
4258 default :
4359 matchesTab = true ;
@@ -46,7 +62,7 @@ export function SupportsCaseList({
4662 // Filter by search query
4763 const matchesSearch =
4864 searchQuery === "" ||
49- ticket . id . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ;
65+ ticket . title . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ;
5066
5167 return matchesTab && matchesSearch ;
5268 } ) ;
@@ -56,28 +72,22 @@ export function SupportsCaseList({
5672 all : tickets . filter (
5773 ( ticket ) =>
5874 searchQuery === "" ||
59- ticket . id . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ,
75+ ticket . title . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ,
6076 ) . length ,
6177 closed : tickets . filter (
6278 ( ticket ) =>
63- ( ticket . status === "resolved" || ticket . status === "closed" ) &&
79+ isTicketClosed ( ticket ) &&
6480 ( searchQuery === "" ||
65- ticket . id . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ) ,
81+ ticket . title . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ) ,
6682 ) . length ,
6783 open : tickets . filter (
6884 ( ticket ) =>
69- ( ( ticket . status as string ) === "in_progress" ||
70- ( ticket . status as string ) === "needs_response" ||
71- ( ticket . status as string ) === "on_hold" ) &&
85+ isTicketOpen ( ticket ) &&
7286 ( searchQuery === "" ||
73- ticket . id . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ) ,
87+ ticket . title . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ) ,
7488 ) . length ,
7589 } ;
7690
77- const _handleSelectCase = ( ticketId : string ) => {
78- router . push ( `/team/${ team . slug } /~/support/cases/${ ticketId } ` ) ;
79- } ;
80-
8191 return (
8292 < div className = "flex flex-col" >
8393 < SupportCaseFilters
@@ -107,33 +117,46 @@ export function SupportsCaseList({
107117 </ div >
108118 </ div >
109119 ) : (
110- < div className = "border bg-card rounded-lg" >
111- { filteredTickets . map ( ( ticket ) => (
112- < div
113- className = "relative px-4 py-5 border-b last:border-b-0 hover:bg-accent/50"
114- key = { ticket . id }
115- >
116- < div className = "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between" >
117- < Link
118- className = "text-foreground font-medium break-all flex-1 text-sm before:absolute before:inset-0"
119- href = { `/team/${ team . slug } /~/support/cases/${ ticket . id } ` }
120+ < TableContainer >
121+ < Table >
122+ < TableHeader >
123+ < TableRow >
124+ < TableHead > Title</ TableHead >
125+ < TableHead className = "w-[150px]" > Status</ TableHead >
126+ < TableHead className = "w-[200px]" > Last Updated</ TableHead >
127+ </ TableRow >
128+ </ TableHeader >
129+ < TableBody >
130+ { filteredTickets . map ( ( ticket ) => (
131+ < TableRow
132+ key = { ticket . title }
133+ linkBox
134+ className = "hover:bg-accent/50 cursor-pointer"
120135 >
121- { ticket . title }
122- </ Link >
123-
124- < div className = "flex items-center gap-3 justify-between" >
125- < Badge variant = { getTicketStatusBadgeVariant ( ticket . status ) } >
126- { getTicketStatusLabel ( ticket . status ) }
127- </ Badge >
128-
129- < div className = "text-muted-foreground text-xs" >
136+ < TableCell className = "py-6" >
137+ < Link
138+ className = "text-foreground font-medium text-sm before:absolute before:inset-0"
139+ href = { `/team/${ team . slug } /~/support/cases/${ ticket . id } ` }
140+ >
141+ { ticket . title }
142+ </ Link >
143+ </ TableCell >
144+ < TableCell >
145+ < Badge
146+ variant = { getTicketStatusBadgeVariant ( ticket . status ) }
147+ className = "text-sm"
148+ >
149+ { getTicketStatusLabel ( ticket . status ) }
150+ </ Badge >
151+ </ TableCell >
152+ < TableCell className = "text-muted-foreground text-sm" >
130153 { format ( new Date ( ticket . updatedAt ) , "MMM d, yyyy" ) }
131- </ div >
132- </ div >
133- </ div >
134- </ div >
135- ) ) }
136- </ div >
154+ </ TableCell >
155+ </ TableRow >
156+ ) ) }
157+ </ TableBody >
158+ </ Table >
159+ </ TableContainer >
137160 ) }
138161 </ div >
139162 ) ;
0 commit comments