1- import React , { useState } from ' react' ;
2- import { useNavigate } from ' react-router-dom' ;
3- import api from ' ../api/axios' ;
4-
1+ import React , { useState , useEffect } from " react" ;
2+ import { useNavigate } from " react-router-dom" ;
3+ import api from " ../api/axios" ;
4+ import { toast , Bounce } from "react-toastify" ;
55const ReceiptsPage = ( ) => {
6+ const [ isMobile , setIsMobile ] = useState ( window . innerWidth <= 767 ) ;
67 const [ file , setFile ] = useState ( null ) ;
78 const [ uploading , setUploading ] = useState ( false ) ;
89 const [ receiptResult , setReceiptResult ] = useState ( null ) ;
9- const [ error , setError ] = useState ( '' ) ;
10+ const [ error , setError ] = useState ( "" ) ;
1011 const navigate = useNavigate ( ) ;
1112
13+ useEffect ( ( ) => {
14+ const handleResize = ( ) => {
15+ return setIsMobile ( window . innerWidth <= 767 ) ;
16+ } ;
17+ window . addEventListener ( "resize" , handleResize ) ;
18+ return ( ) => window . removeEventListener ( "resize" , handleResize ) ;
19+ } , [ ] ) ;
20+
1221 const handleFileChange = ( e ) => {
1322 setFile ( e . target . files [ 0 ] ) ;
1423 setReceiptResult ( null ) ;
15- setError ( '' ) ;
24+ setError ( "" ) ;
1625 } ;
1726
1827 const handleSubmit = async ( e ) => {
1928 e . preventDefault ( ) ;
2029 if ( ! file ) {
21- setError ( ' Please select a file to upload.' ) ;
30+ setError ( " Please select a file to upload." ) ;
2231 return ;
2332 }
2433
2534 const formData = new FormData ( ) ;
26- formData . append ( ' receipt' , file ) ;
27-
35+ formData . append ( " receipt" , file ) ;
36+
2837 try {
2938 setUploading ( true ) ;
30- setError ( '' ) ;
31- const response = await api . post ( ' /receipts/upload' , formData , {
39+ setError ( "" ) ;
40+ const response = await api . post ( " /receipts/upload" , formData , {
3241 headers : {
33- ' Content-Type' : ' multipart/form-data' ,
42+ " Content-Type" : " multipart/form-data" ,
3443 } ,
3544 } ) ;
3645 setReceiptResult ( response . data ) ;
37- alert ( 'Receipt processed successfully and transaction created! Redirecting to dashboard...' ) ;
38- navigate ( '/dashboard' ) ;
46+
47+ toast . success ( "Receipt processed successfully and transaction created!" , {
48+ position : "top-right" ,
49+ autoClose : 3000 ,
50+ hideProgressBar : false ,
51+ closeOnClick : false ,
52+ pauseOnHover : true ,
53+ draggable : true ,
54+ progress : undefined ,
55+ style : {
56+ fontSize : "18px" , // increases text size
57+ padding : "16px 24px" , // increases toast size
58+ minWidth : "500px" , // optional: increase width
59+ } ,
60+ theme : "light" ,
61+ transition : Bounce ,
62+ } ) ;
3963 } catch ( err ) {
40- setError ( ' Upload failed. Please try again.' ) ;
64+ setError ( " Upload failed. Please try again." ) ;
4165 console . error ( err ) ;
4266 } finally {
4367 setUploading ( false ) ;
@@ -46,47 +70,79 @@ const ReceiptsPage = () => {
4670
4771 return (
4872 < >
49- < h1 className = "text-3xl font-bold text-gray-900 dark:text-gray-100 mb-6" > Upload Receipt</ h1 >
73+ < h1 className = "text-3xl font-bold text-gray-900 dark:text-gray-100 mb-6" >
74+ Upload Receipt
75+ </ h1 >
5076 < div className = "grid grid-cols-1 md:grid-cols-2 gap-8" >
51-
5277 < div className = "bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md" >
5378 < form onSubmit = { handleSubmit } >
54- < label className = "block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300" > Select a receipt file (JPG, PNG, PDF)</ label >
55- < input
79+ < label className = "block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300" >
80+ Select a receipt file (JPG, PNG, PDF)
81+ </ label >
82+ < input
5683 type = "file"
5784 onChange = { handleFileChange }
5885 className = "block w-full text-sm text-gray-500 dark:text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-blue-50 dark:file:bg-blue-900/50 file:text-blue-700 dark:file:text-blue-300 hover:file:bg-blue-100 dark:hover:file:bg-blue-800"
5986 accept = ".jpeg,.jpg,.png,.pdf"
6087 />
61- < button
62- type = "submit"
88+ < button
89+ type = "submit"
6390 disabled = { uploading }
6491 className = "mt-4 w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-blue-300"
6592 >
66- { uploading ? ' Processing...' : ' Upload & Create Transaction' }
93+ { uploading ? " Processing..." : " Upload & Create Transaction" }
6794 </ button >
6895 { error && < p className = "mt-2 text-sm text-red-600" > { error } </ p > }
6996 </ form >
7097 </ div >
7198
7299 < div className = "bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md" >
73- < h2 className = "text-xl font-bold text-gray-800 dark:text-gray-200 mb-4" > Last Upload Result</ h2 >
100+ < h2 className = "text-xl font-bold text-gray-800 dark:text-gray-200 mb-4" >
101+ Last Upload Result
102+ </ h2 >
74103 { receiptResult ? (
75104 < div >
76- < p className = "text-gray-700 dark:text-gray-300" > < strong > Merchant:</ strong > { receiptResult . extractedData . merchant } </ p >
77- < p className = "text-gray-700 dark:text-gray-300" > < strong > Amount:</ strong > { receiptResult . extractedData . amount . toFixed ( 2 ) } </ p >
78- < p className = "text-gray-700 dark:text-gray-300" > < strong > Category:</ strong > { receiptResult . extractedData . category } </ p >
79- < p className = "text-gray-700 dark:text-gray-300" > < strong > Date:</ strong > { new Date ( receiptResult . extractedData . date ) . toLocaleDateString ( ) } </ p >
80- < img src = { `http://localhost:5001${ receiptResult . fileUrl } ` } alt = "Uploaded Receipt" className = "mt-4 rounded-lg max-w-full h-auto" />
105+ < p className = "text-gray-700 dark:text-gray-300" >
106+ < strong > Merchant:</ strong > { " " }
107+ { receiptResult . extractedData . merchant }
108+ </ p >
109+ < p className = "text-gray-700 dark:text-gray-300" >
110+ < strong > Amount:</ strong > { " " }
111+ { receiptResult . extractedData . amount . toFixed ( 2 ) }
112+ </ p >
113+ < p className = "text-gray-700 dark:text-gray-300" >
114+ < strong > Category:</ strong > { " " }
115+ { receiptResult . extractedData . category }
116+ </ p >
117+ < p className = "text-gray-700 dark:text-gray-300" >
118+ < strong > Date:</ strong > { " " }
119+ { new Date (
120+ receiptResult . extractedData . date
121+ ) . toLocaleDateString ( ) }
122+ </ p >
123+ < img
124+ src = { `http://localhost:5000${ receiptResult . fileUrl } ` }
125+ alt = "Uploaded Receipt"
126+ className = "mt-4 rounded-lg max-w-full h-auto"
127+ />
81128 </ div >
82129 ) : (
83- < p className = "text-gray-500 dark:text-gray-400" > Upload a receipt to see the extracted data here.</ p >
130+ < p className = "text-gray-500 dark:text-gray-400" >
131+ Upload a receipt to see the extracted data here.
132+ </ p >
84133 ) }
85134 </ div >
86-
135+ { isMobile && (
136+ < button
137+ onClick = { ( ) => navigate ( "/dashboard" ) }
138+ className = "mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 w-full"
139+ >
140+ Go to Dashboard
141+ </ button >
142+ ) }
87143 </ div >
88144 </ >
89145 ) ;
90146} ;
91147
92- export default ReceiptsPage ;
148+ export default ReceiptsPage ;
0 commit comments