@@ -4,7 +4,7 @@ import { apiFetch } from '@/lib/api';
44import { Card , CardContent , CardHeader , CardTitle , CardDescription } from '@/components/ui/card' ;
55import { Button } from '@/components/ui/button' ;
66import { Link } from 'react-router-dom' ;
7- import { Mail , Users , Trash2 , ExternalLink } from 'lucide-react' ;
7+ import { Mail , Users , Trash2 , ExternalLink , Star } from 'lucide-react' ;
88import toast from 'react-hot-toast' ;
99import { formatDistanceToNow } from 'date-fns' ;
1010import { Tabs , TabsContent , TabsList , TabsTrigger } from "@/components/ui/tabs" ;
@@ -15,12 +15,15 @@ interface Mailbox {
1515 address : string ;
1616 created_at : string ;
1717 email_count ?: number ;
18+ is_favorite ?: boolean ;
19+ forward_to ?: string ;
1820}
1921
2022export default function Dashboard ( ) {
2123 const { user } = useAuth ( ) ;
2224 const [ mailboxes , setMailboxes ] = useState < Mailbox [ ] > ( [ ] ) ;
2325 const [ isLoading , setIsLoading ] = useState ( false ) ;
26+ const [ filter , setFilter ] = useState < 'all' | 'favorites' | 'forwarding' > ( 'all' ) ;
2427
2528 const isMailboxUser = user ?. role === 'mailbox' ;
2629 const isAdmin = user ?. role === 'admin' ;
@@ -29,9 +32,13 @@ export default function Dashboard() {
2932 if ( isMailboxUser ) return ;
3033 setIsLoading ( true ) ;
3134 try {
32- const data = await apiFetch < any > ( '/api/mailboxes?limit=10' ) ;
33- if ( data . success && Array . isArray ( data . results ) ) {
34- setMailboxes ( data . results ) ;
35+ let url = '/api/mailboxes?limit=20' ;
36+ if ( filter === 'favorites' ) url += '&favorite=true' ;
37+ if ( filter === 'forwarding' ) url += '&forward=true' ;
38+
39+ const data = await apiFetch < any > ( url ) ;
40+ if ( data . success && Array . isArray ( data . results || data . list ) ) {
41+ setMailboxes ( data . results || data . list ) ;
3542 }
3643 } catch ( error ) {
3744 console . error ( 'Failed to fetch mailboxes' ) ;
@@ -42,7 +49,22 @@ export default function Dashboard() {
4249
4350 useEffect ( ( ) => {
4451 fetchMailboxes ( ) ;
45- } , [ user ] ) ;
52+ } , [ user , filter ] ) ;
53+
54+ const toggleFavorite = async ( mailbox : Mailbox ) => {
55+ try {
56+ await apiFetch ( '/api/mailbox/favorite' , {
57+ method : 'POST' ,
58+ body : JSON . stringify ( { mailbox_id : mailbox . id } )
59+ } ) ;
60+ setMailboxes ( mailboxes . map ( m =>
61+ m . id === mailbox . id ? { ...m , is_favorite : ! m . is_favorite } : m
62+ ) ) ;
63+ toast . success ( mailbox . is_favorite ? 'Removed from favorites' : 'Added to favorites' ) ;
64+ } catch ( error ) {
65+ toast . error ( 'Failed to update favorite status' ) ;
66+ }
67+ } ;
4668
4769 const handleDeleteMailbox = async ( id : number ) => {
4870 if ( ! confirm ( 'Delete this mailbox?' ) ) return ;
@@ -121,11 +143,37 @@ export default function Dashboard() {
121143 </ div >
122144
123145 < Card className = "col-span-3" >
124- < CardHeader >
125- < CardTitle > Recent Mailboxes</ CardTitle >
126- < CardDescription >
127- Manage your temporary mailboxes here.
128- </ CardDescription >
146+ < CardHeader className = "flex flex-row items-center justify-between" >
147+ < div >
148+ < CardTitle > Recent Mailboxes</ CardTitle >
149+ < CardDescription >
150+ Manage your temporary mailboxes here.
151+ </ CardDescription >
152+ </ div >
153+ < div className = "flex bg-muted p-1 rounded-md" >
154+ < Button
155+ variant = { filter === 'all' ? 'secondary' : 'ghost' }
156+ size = "sm"
157+ onClick = { ( ) => setFilter ( 'all' ) }
158+ >
159+ All
160+ </ Button >
161+ < Button
162+ variant = { filter === 'favorites' ? 'secondary' : 'ghost' }
163+ size = "sm"
164+ onClick = { ( ) => setFilter ( 'favorites' ) }
165+ className = "gap-2"
166+ >
167+ < Star className = "h-3 w-3" /> Favorites
168+ </ Button >
169+ < Button
170+ variant = { filter === 'forwarding' ? 'secondary' : 'ghost' }
171+ size = "sm"
172+ onClick = { ( ) => setFilter ( 'forwarding' ) }
173+ >
174+ Forwarding
175+ </ Button >
176+ </ div >
129177 </ CardHeader >
130178 < CardContent >
131179 < div className = "space-y-4" >
@@ -137,11 +185,26 @@ export default function Dashboard() {
137185 < Mail className = "h-4 w-4 text-primary" />
138186 </ div >
139187 < div >
140- < p className = "font-medium" > { mb . address } </ p >
188+ < div className = "flex items-center gap-2" >
189+ < p className = "font-medium" > { mb . address } </ p >
190+ { mb . forward_to && (
191+ < span className = "text-[10px] bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300 px-1.5 py-0.5 rounded-full" >
192+ Forwarding
193+ </ span >
194+ ) }
195+ </ div >
141196 < p className = "text-xs text-muted-foreground" > Created { formatDistanceToNow ( new Date ( mb . created_at ) , { addSuffix : true } ) } </ p >
142197 </ div >
143198 </ div >
144199 < div className = "flex items-center gap-2" >
200+ < Button
201+ variant = "ghost"
202+ size = "icon"
203+ onClick = { ( ) => toggleFavorite ( mb ) }
204+ className = { mb . is_favorite ? "text-yellow-500 hover:text-yellow-600 hover:bg-yellow-100/50" : "text-muted-foreground hover:text-yellow-500" }
205+ >
206+ < Star className = { `h-4 w-4 ${ mb . is_favorite ? "fill-current" : "" } ` } />
207+ </ Button >
145208 < Button variant = "ghost" size = "icon" asChild >
146209 < Link to = { `/mailbox?mailbox=${ mb . address } ` } > < ExternalLink className = "h-4 w-4" /> </ Link >
147210 </ Button >
0 commit comments