11import React , { useState } from 'react' ;
22
3- import { Button , FileDropzone , Heading } from '@douglasneuroinformatics/libui/components' ;
3+ import { Button , FileDropzone , Heading , Spinner } from '@douglasneuroinformatics/libui/components' ;
44import { useDownload , useTranslation } from '@douglasneuroinformatics/libui/hooks' ;
55import { useNotificationsStore } from '@douglasneuroinformatics/libui/hooks' ;
66import type { AnyUnilingualFormInstrument } from '@opendatacapture/runtime-core' ;
@@ -16,6 +16,7 @@ import { createUploadTemplateCSV, processInstrumentCSV, reformatInstrumentData }
1616
1717export const UploadPage = ( ) => {
1818 const [ file , setFile ] = useState < File | null > ( null ) ;
19+ const [ isLoading , setIsLoading ] = useState ( false ) ;
1920 const download = useDownload ( ) ;
2021 const addNotification = useNotificationsStore ( ( store ) => store . addNotification ) ;
2122 const currentGroup = useAppStore ( ( store ) => store . currentGroup ) ;
@@ -31,30 +32,43 @@ export const UploadPage = () => {
3132 } ;
3233
3334 const handleInstrumentCSV = async ( ) => {
34- const processedDataResult = await processInstrumentCSV ( file ! , instrument ! ) ;
35- if ( processedDataResult . success ) {
36- const reformattedData = reformatInstrumentData ( {
37- currentGroup,
38- data : processedDataResult . value ,
39- instrument : instrument !
40- } ) ;
41- if ( reformattedData . records . length > 1000 ) {
35+ try {
36+ setIsLoading ( true ) ;
37+ const processedDataResult = await processInstrumentCSV ( file ! , instrument ! ) ;
38+ if ( processedDataResult . success ) {
39+ const reformattedData = reformatInstrumentData ( {
40+ currentGroup,
41+ data : processedDataResult . value ,
42+ instrument : instrument !
43+ } ) ;
44+ if ( reformattedData . records . length > 1000 ) {
45+ addNotification ( {
46+ message : t ( {
47+ en : 'Lots of entries loading, please wait...' ,
48+ fr : 'Beaucoup de données, veuillez patienter...'
49+ } ) ,
50+ type : 'info'
51+ } ) ;
52+ }
53+ await uploadInstrumentRecordsMutation . mutateAsync ( reformattedData ) ;
54+ } else {
4255 addNotification ( {
43- message : t ( {
44- en : 'Lots of entries loading, please wait...' ,
45- fr : 'Beaucoup de données, veuillez patienter...'
46- } ) ,
47- type : 'info'
56+ message : processedDataResult . message ,
57+ type : 'error'
4858 } ) ;
4959 }
50- uploadInstrumentRecordsMutation . mutate ( reformattedData ) ;
51- } else {
60+ setFile ( null ) ;
61+ } catch ( error ) {
5262 addNotification ( {
53- message : processedDataResult . message ,
63+ message : t ( {
64+ en : 'An error has happended within the request' ,
65+ fr : "Une erreur s'est produite lors du téléversement."
66+ } ) ,
5467 type : 'error'
5568 } ) ;
69+ } finally {
70+ setIsLoading ( false ) ;
5671 }
57- setFile ( null ) ;
5872 } ;
5973
6074 if ( ! instrument ) {
@@ -71,28 +85,42 @@ export const UploadPage = () => {
7185 } ) }
7286 </ Heading >
7387 </ PageHeader >
74- < div className = "mx-auto flex w-full max-w-3xl flex-grow flex-col justify-center" >
75- < FileDropzone
76- acceptedFileTypes = { {
77- 'text/csv' : [ '.csv' ]
78- } }
79- className = "flex h-80 w-full flex-col"
80- file = { file }
81- setFile = { setFile }
82- />
83- < div className = "mt-4 flex justify-between space-x-2" >
84- < Button disabled = { ! ( file && instrument ) } variant = { 'primary' } onClick = { handleInstrumentCSV } >
85- { t ( 'core.submit' ) }
86- </ Button >
87- < Button className = "gap-1.5" disabled = { ! instrument } variant = { 'primary' } onClick = { handleTemplateDownload } >
88- < DownloadIcon />
89- { t ( {
90- en : 'Download Template' ,
91- fr : 'Télécharger le modèle'
92- } ) }
93- </ Button >
88+ { ! isLoading ? (
89+ < div className = "mx-auto flex w-full max-w-3xl flex-grow flex-col justify-center" >
90+ < FileDropzone
91+ acceptedFileTypes = { {
92+ 'text/csv' : [ '.csv' ]
93+ } }
94+ className = "flex h-80 w-full flex-col"
95+ file = { file }
96+ setFile = { setFile }
97+ />
98+ < div className = "mt-4 flex justify-between space-x-2" >
99+ < Button disabled = { ! ( file && instrument ) } variant = { 'primary' } onClick = { handleInstrumentCSV } >
100+ { t ( 'core.submit' ) }
101+ </ Button >
102+ < Button className = "gap-1.5" disabled = { ! instrument } variant = { 'primary' } onClick = { handleTemplateDownload } >
103+ < DownloadIcon />
104+ { t ( {
105+ en : 'Download Template' ,
106+ fr : 'Télécharger le modèle'
107+ } ) }
108+ </ Button >
109+ </ div >
94110 </ div >
95- </ div >
111+ ) : (
112+ < >
113+ < div className = "mx-auto flex w-full max-w-3xl flex-grow flex-col justify-center" >
114+ < Spinner className = "mx-auto size-1/2" > </ Spinner >
115+ < Heading className = "text-center" variant = "h3" >
116+ { t ( {
117+ en : 'Data currently uploading...' ,
118+ fr : 'Données en cours de téléchargement...'
119+ } ) }
120+ </ Heading >
121+ </ div >
122+ </ >
123+ ) }
96124 </ React . Fragment >
97125 ) ;
98126} ;
0 commit comments