1+ import Archive from "lucide-react/icons/archive" ;
2+ import ArchiveRestore from "lucide-react/icons/archive-restore" ;
13import Inbox from "lucide-react/icons/inbox" ;
24import Paperclip from "lucide-react/icons/paperclip" ;
35import PenSquare from "lucide-react/icons/pen-square" ;
@@ -36,14 +38,14 @@ import { Textarea } from "@/components/ui/textarea";
3638import {
3739 AdminMessageDirection ,
3840 type AdminThreadMessage ,
39- type AdminThreadStatus ,
4041 type AdminThreadSummary ,
42+ type AdminThreadView ,
4143 type AdminUser ,
4244 adminSupportAttachmentUrl ,
4345 createAdminSupportThread ,
4446 fetchAdminSupportMessageBody ,
4547 sendAdminSupportReply ,
46- updateAdminSupportThreadStatus ,
48+ updateAdminSupportThreadArchived ,
4749 useAdminSupportThread ,
4850 useAdminSupportThreads ,
4951 useAdminSupportUnreadCount ,
@@ -52,11 +54,10 @@ import {
5254import { formatDate } from "@/utils/date" ;
5355import { cn } from "@/utils/utils" ;
5456
55- const STATUS_FILTERS : { value : AdminThreadStatus | "all" ; label : string } [ ] = [
57+ const VIEW_FILTERS : { value : AdminThreadView ; label : string } [ ] = [
58+ { value : "inbox" , label : "Inbox" } ,
59+ { value : "archived" , label : "Archived" } ,
5660 { value : "all" , label : "All" } ,
57- { value : "open" , label : "Open" } ,
58- { value : "pending" , label : "Pending" } ,
59- { value : "closed" , label : "Closed" } ,
6061] ;
6162
6263export function AdminSupportPage ( ) {
@@ -67,20 +68,13 @@ export function AdminSupportPage() {
6768 } , [ setBreadcrumbs ] ) ;
6869
6970 const [ page , setPage ] = useState ( 1 ) ;
70- const [ statusFilter , setStatusFilter ] = useState < AdminThreadStatus | "all" > (
71- "all"
72- ) ;
71+ const [ view , setView ] = useState < AdminThreadView > ( "inbox" ) ;
7372 const [ searchInput , setSearchInput ] = useState ( "" ) ;
7473 const [ search , setSearch ] = useState ( "" ) ;
7574 const limit = 30 ;
7675
7776 const { threads, pagination, threadsError, isThreadsLoading, mutateThreads } =
78- useAdminSupportThreads (
79- page ,
80- limit ,
81- statusFilter === "all" ? undefined : statusFilter ,
82- search || undefined
83- ) ;
77+ useAdminSupportThreads ( page , limit , view , search || undefined ) ;
8478 const { mutateUnreadCount } = useAdminSupportUnreadCount ( ) ;
8579
8680 const [ selectedThreadId , setSelectedThreadId ] = useState < string | null > ( null ) ;
@@ -134,17 +128,17 @@ export function AdminSupportPage() {
134128 </ form >
135129
136130 < Select
137- value = { statusFilter }
131+ value = { view }
138132 onValueChange = { ( v ) => {
139- setStatusFilter ( v as AdminThreadStatus | "all" ) ;
133+ setView ( v as AdminThreadView ) ;
140134 setPage ( 1 ) ;
141135 } }
142136 >
143137 < SelectTrigger className = "w-36 h-10" >
144138 < SelectValue />
145139 </ SelectTrigger >
146140 < SelectContent >
147- { STATUS_FILTERS . map ( ( f ) => (
141+ { VIEW_FILTERS . map ( ( f ) => (
148142 < SelectItem key = { f . value } value = { f . value } >
149143 { f . label }
150144 </ SelectItem >
@@ -214,7 +208,7 @@ function ThreadList({
214208} ) {
215209 return (
216210 < div className = "flex flex-col overflow-hidden lg:border-r" >
217- < div className = "px-4 py-2" >
211+ < div className = "px-4 py-2 border-b " >
218212 < Button className = "w-full h-10" onClick = { onCompose } >
219213 < PenSquare className = "h-4 w-4 mr-2" />
220214 New thread
@@ -336,7 +330,7 @@ function ThreadDetail({
336330
337331 const [ replyText , setReplyText ] = useState ( "" ) ;
338332 const [ isSending , setIsSending ] = useState ( false ) ;
339- const [ isUpdatingStatus , setIsUpdatingStatus ] = useState ( false ) ;
333+ const [ isUpdatingArchived , setIsUpdatingArchived ] = useState ( false ) ;
340334
341335 // Reset the composer when switching threads.
342336 useEffect ( ( ) => {
@@ -373,16 +367,19 @@ function ThreadDetail({
373367 }
374368 } ;
375369
376- const onStatusChange = async ( status : AdminThreadStatus ) => {
377- setIsUpdatingStatus ( true ) ;
370+ const isArchived = thread . archivedAt !== null ;
371+ const onToggleArchived = async ( ) => {
372+ setIsUpdatingArchived ( true ) ;
378373 try {
379- await updateAdminSupportThreadStatus ( threadId , status ) ;
374+ await updateAdminSupportThreadArchived ( threadId , ! isArchived ) ;
380375 await mutateThread ( ) ;
381376 onMutated ( ) ;
382377 } catch ( e ) {
383- toast . error ( e instanceof Error ? e . message : "Failed to update status" ) ;
378+ toast . error (
379+ e instanceof Error ? e . message : "Failed to update archive state"
380+ ) ;
384381 } finally {
385- setIsUpdatingStatus ( false ) ;
382+ setIsUpdatingArchived ( false ) ;
386383 }
387384 } ;
388385
@@ -414,20 +411,24 @@ function ThreadDetail({
414411 </ p >
415412 </ div >
416413 </ div >
417- < Select
418- value = { thread . status }
419- disabled = { isUpdatingStatus }
420- onValueChange = { ( v ) => onStatusChange ( v as AdminThreadStatus ) }
414+ < Button
415+ variant = "outline"
416+ className = "h-10 w-36 shrink-0"
417+ onClick = { onToggleArchived }
418+ disabled = { isUpdatingArchived }
421419 >
422- < SelectTrigger className = "w-36 h-10 shrink-0" >
423- < SelectValue />
424- </ SelectTrigger >
425- < SelectContent >
426- < SelectItem value = "open" > Open</ SelectItem >
427- < SelectItem value = "pending" > Pending</ SelectItem >
428- < SelectItem value = "closed" > Closed</ SelectItem >
429- </ SelectContent >
430- </ Select >
420+ { isArchived ? (
421+ < >
422+ < ArchiveRestore className = "h-4 w-4 mr-2" />
423+ Unarchive
424+ </ >
425+ ) : (
426+ < >
427+ < Archive className = "h-4 w-4 mr-2" />
428+ Archive
429+ </ >
430+ ) }
431+ </ Button >
431432 </ div >
432433
433434 < div className = "flex-1 overflow-y-auto px-5 py-4 space-y-6" >
0 commit comments