1
- import { useState , useCallback } from 'react' ;
1
+ import { useState , useCallback , useEffect } from 'react' ;
2
2
import { GroupedData , ParsedUser } from '@/types' ;
3
3
import Papa from 'papaparse' ;
4
4
import { mapLicensesData } from '@/helpers/filter-helpers' ;
5
5
import _ from 'lodash' ;
6
- import { ErrorCodes , LicenseError } from '@/types/errors' ;
6
+ import { LicenseError } from '@/types/errors' ;
7
+ import localforage from 'localforage' ;
7
8
8
9
export interface UseLicenseDataReturn {
9
10
groupedData : GroupedData ;
@@ -15,50 +16,80 @@ export interface UseLicenseDataReturn {
15
16
handleFileDrop : ( event : React . DragEvent < HTMLDivElement > ) => Promise < void > ;
16
17
}
17
18
19
+ const CACHE_KEY = 'licenseDataCache' ;
20
+
18
21
export function useLicenseData ( ) : UseLicenseDataReturn {
19
22
const [ groupedData , setGroupedData ] = useState < GroupedData > ( { } ) ;
20
23
const [ loading , setLoading ] = useState ( false ) ;
21
24
const [ fileName , setFileName ] = useState ( '' ) ;
22
25
const [ error , setError ] = useState < LicenseError | null > ( null ) ;
23
26
27
+ useEffect ( ( ) => {
28
+ const loadCachedData = async ( ) => {
29
+ const cachedData = await localforage . getItem < { groupedData : GroupedData ; fileName : string } > ( CACHE_KEY ) ;
30
+ if ( cachedData ) {
31
+ setGroupedData ( cachedData . groupedData ) ;
32
+ setFileName ( cachedData . fileName ) ;
33
+ }
34
+ } ;
35
+ loadCachedData ( ) ;
36
+ } , [ ] ) ;
37
+
24
38
const processFile = async ( file : File ) => {
25
39
if ( ! file ) {
26
40
setFileName ( '' ) ;
27
41
setGroupedData ( { } ) ;
28
42
return ;
29
43
}
30
-
44
+
45
+ setError ( null ) ; // Reset error state before processing
46
+
47
+ const fileExtension = file . name . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
48
+ if ( file . type !== 'text/csv' && fileExtension !== 'csv' ) {
49
+ const licenseError = new LicenseError (
50
+ 'Invalid file type' ,
51
+ 'INVALID_FILE_TYPE' ,
52
+ new Error ( 'Only CSV files are allowed' )
53
+ ) ;
54
+ setError ( licenseError ) ;
55
+ console . error ( licenseError ) ;
56
+ return ;
57
+ }
58
+
31
59
setLoading ( true ) ;
32
60
try {
33
61
const text = await file . text ( ) ;
34
- const result = Papa . parse < ParsedUser > ( text , {
62
+ Papa . parse < ParsedUser > ( text , {
35
63
header : true ,
36
64
skipEmptyLines : true ,
37
65
transformHeader : header => header . trim ( ) ,
38
- transform : value => value . trim ( )
39
- } ) ;
40
-
41
- if ( result . errors . length > 0 ) {
42
- throw new Error ( 'Error parsing CSV: ' + result . errors [ 0 ] . message ) ;
43
- }
66
+ transform : value => value . trim ( ) ,
67
+ complete : ( results ) => {
68
+ if ( results . errors . length > 0 ) {
69
+ throw new Error ( 'Error parsing CSV: ' + results . errors . map ( e => e . message ) . join ( ', ' ) ) ;
70
+ }
44
71
45
- const licenses = result . data ;
46
- const mappedData = mapLicensesData ( licenses ) ;
47
- const grouped = _ . groupBy ( mappedData , 'department' ) ;
48
- const sortedGrouped = _ . mapValues ( grouped , users =>
49
- _ . sortBy ( users , [ 'displayName' ] )
50
- ) ;
51
-
52
- setGroupedData ( sortedGrouped ) ;
53
- setFileName ( file . name ) ;
72
+ const licenses = results . data ;
73
+ const mappedData = mapLicensesData ( licenses ) ;
74
+ const grouped = _ . groupBy ( mappedData , 'department' ) ;
75
+ const sortedGrouped = _ . mapValues ( grouped , users =>
76
+ _ . sortBy ( users , [ 'displayName' ] )
77
+ ) ;
78
+
79
+ setGroupedData ( sortedGrouped ) ;
80
+ setFileName ( file . name ) ;
81
+
82
+ localforage . setItem ( CACHE_KEY , { groupedData : sortedGrouped , fileName : file . name } ) ;
83
+ }
84
+ } ) ;
54
85
} catch ( error ) {
55
86
const licenseError = new LicenseError (
56
87
'Error loading file' ,
57
- ErrorCodes . FILE_PARSE_ERROR ,
88
+ ' FILE_PARSE_ERROR' ,
58
89
error
59
90
) ;
60
91
setError ( licenseError ) ;
61
- console . error ( licenseError ) ;
92
+ console . error ( 'Error details:' , error ) ;
62
93
} finally {
63
94
setLoading ( false ) ;
64
95
}
0 commit comments