11import { useState } from 'react' ;
22import { useRouter } from 'next/router' ;
33import { formatDistanceToNow } from 'date-fns' ;
4- import { ChevronRight , CheckSquare , Paperclip , X , Star , AlarmClock } from 'lucide-react' ;
4+ import { ChevronRight , CheckSquare , Paperclip , X , Star , AlarmClock , Zap , Loader2 } from 'lucide-react' ;
55import clsx from 'clsx' ;
66import toast from 'react-hot-toast' ;
77import type { Email } from '@/lib/types' ;
@@ -14,6 +14,7 @@ interface EmailCardProps {
1414 email : Email ;
1515 className ?: string ;
1616 onDismiss ?: ( id : string ) => void ;
17+ onProcessed ?: ( ) => void ;
1718 selected ?: boolean ;
1819 onToggleSelect ?: ( ) => void ;
1920}
@@ -35,9 +36,10 @@ function getGradient(name: string) {
3536 return AVATAR_GRADIENTS [ code ] ;
3637}
3738
38- export default function EmailCard ( { email, className, onDismiss, selected, onToggleSelect } : EmailCardProps ) {
39+ export default function EmailCard ( { email, className, onDismiss, onProcessed , selected, onToggleSelect } : EmailCardProps ) {
3940 const router = useRouter ( ) ;
4041 const [ dismissing , setDismissing ] = useState ( false ) ;
42+ const [ processing , setProcessing ] = useState ( false ) ;
4143 const [ starred , setStarred ] = useState ( email . is_starred ) ;
4244 const [ snoozeOpen , setSnoozeOpen ] = useState ( false ) ;
4345
@@ -71,6 +73,21 @@ export default function EmailCard({ email, className, onDismiss, selected, onTog
7173 }
7274 } ;
7375
76+ const handleProcess = async ( e : React . MouseEvent ) => {
77+ e . stopPropagation ( ) ;
78+ setProcessing ( true ) ;
79+ try {
80+ await emailsApi . processEmail ( email . id ) ;
81+ toast . success ( 'Processing with AI…' ) ;
82+ onProcessed ?.( ) ;
83+ } catch ( err : unknown ) {
84+ const msg = ( err as { response ?: { data ?: { detail ?: string } } } ) ?. response ?. data ?. detail ;
85+ toast . error ( msg || 'Failed to process email' ) ;
86+ } finally {
87+ setProcessing ( false ) ;
88+ }
89+ } ;
90+
7491 const handleSnoozeClick = ( e : React . MouseEvent ) => {
7592 e . stopPropagation ( ) ;
7693 setSnoozeOpen ( true ) ;
@@ -181,6 +198,17 @@ export default function EmailCard({ email, className, onDismiss, selected, onTog
181198
182199 { /* Badges row */ }
183200 < div className = "mt-2 flex items-center gap-1.5 sm:gap-2 flex-wrap" >
201+ { /* Process with AI button — only shown for unprocessed emails */ }
202+ { ! email . processed && ! email . ai_analysis && (
203+ < button
204+ onClick = { handleProcess }
205+ disabled = { processing }
206+ className = "inline-flex items-center gap-1 rounded-full bg-primary-50 dark:bg-primary-900/30 px-2 py-0.5 text-xs font-medium text-primary-700 dark:text-primary-300 border border-primary-200 dark:border-primary-700 hover:bg-primary-100 dark:hover:bg-primary-900/50 transition-colors"
207+ >
208+ { processing ? < Loader2 className = "h-3 w-3 animate-spin" /> : < Zap className = "h-3 w-3" /> }
209+ { processing ? 'Processing…' : 'Process with AI' }
210+ </ button >
211+ ) }
184212 { analysis ?. category && (
185213 < CategoryBadge category = { analysis . category } size = "sm" />
186214 ) }
0 commit comments