77 AppBar ,
88 Box ,
99 Button ,
10+ CssBaseline ,
1011 Link ,
1112 TextField ,
1213 Toolbar ,
@@ -58,11 +59,19 @@ const columns = [{
5859 } ,
5960} ] ;
6061
62+ function getFetchHeader ( body ) {
63+ return {
64+ method : 'POST' ,
65+ headers : { 'Content-Type' : 'application/text;charset=utf-8' } ,
66+ body : body
67+ } ;
68+ }
69+
6170function GridToolbarDownload ( props ) {
6271 let color = useTheme ( ) . palette . primary . main ;
6372 let args = "" ;
6473 let join = "" ;
65- console . log ( props . rows ) ;
74+
6675 props . selections . forEach ( i => {
6776 args += join + "f=" + encodeURIComponent ( props . rows [ i ] . fileName ) ;
6877 join = "&" ;
@@ -92,8 +101,91 @@ function AppToolbar(props) {
92101
93102function FileList ( props ) {
94103 const [ selectionModel , setSelectionModel ] = useState ( [ ] ) ;
104+
105+ return (
106+ < DataGrid rows = { props . rows }
107+ columns = { columns }
108+ pageSize = { 5 }
109+ components = { { Toolbar : AppToolbar } }
110+ componentsProps = { { toolbar : { selections : selectionModel , rows : props . rows } } }
111+ onSelectionModelChange = { ( model ) => setSelectionModel ( model ) }
112+ selectionModel = { selectionModel }
113+ rowsPerPageOptions = { [ 5 ] }
114+ checkboxSelection
115+ disableSelectionOnClick />
116+ ) ;
117+ }
118+
119+ function TokenInput ( props ) {
120+ const [ token , setToken ] = useState ( "" ) ;
121+ const [ error , setError ] = useState ( false ) ;
122+
123+ const onClick = ( ) => {
124+ const validate = async ( ) => {
125+ let response = await fetch ( '/api/files' , getFetchHeader ( "token=" + token ) ) ;
126+ let data = await response . json ( ) ;
127+ if ( data . error ) {
128+ setError ( true ) ;
129+ } else {
130+ props . setRows ( data ) ;
131+ props . setToken ( token ) ;
132+ }
133+ } ;
134+ if ( token ) {
135+ validate ( ) . catch ( console . error ) ;
136+ }
137+ } ;
138+
139+ const onChange = ( event ) => {
140+ setToken ( event . target . value ) ;
141+ if ( ! event . target . value ) {
142+ setError ( false ) ;
143+ }
144+ } ;
145+
146+ const onKeyPress = ( event ) => {
147+ if ( event . key === 'Enter' ) {
148+ onClick ( ) ;
149+ }
150+ } ;
151+
152+ const help = "Enter the access token displayed on the SmallBASIC [About] screen." ;
153+ let helperText = error ? "Invalid token. " + help : help ;
154+
155+ return (
156+ < Box sx = { { display : 'flex' , justifyContent : 'center' , alignItems : 'center' , height : '100%' } } >
157+ < Box sx = { { display : 'flex' , flexDirection : 'column' , marginBottom : '10em' } } >
158+ < Box sx = { { marginBottom : '1em' } } >
159+ < TextField sx = { { width : '20em' } }
160+ error = { error }
161+ value = { token }
162+ onChange = { onChange }
163+ onKeyPress = { onKeyPress }
164+ helperText = { helperText }
165+ label = "Enter your access token" />
166+ </ Box >
167+ < Box >
168+ < Button onClick = { onClick } variant = "contained" > Submit</ Button >
169+ </ Box >
170+ </ Box >
171+ </ Box >
172+ ) ;
173+ }
174+
175+ export default function App ( ) {
176+ const [ token , setToken ] = useState ( null ) ;
177+ const [ rows , setRows ] = useState ( [ ] ) ;
178+
179+ let content ;
180+ if ( token ) {
181+ content = < FileList rows = { rows } /> ;
182+ } else {
183+ content = < TokenInput setRows = { setRows } setToken = { setToken } token = { token } /> ;
184+ }
185+
95186 return (
96- < Box sx = { { flexGrow : 1 } } >
187+ < Box >
188+ < CssBaseline />
97189 < AppBar position = "static" >
98190 < Toolbar >
99191 < Typography variant = "h6" component = "div" sx = { { flexGrow : 1 } } >
@@ -109,41 +201,8 @@ function FileList(props) {
109201 </ Toolbar >
110202 </ AppBar >
111203 < Box sx = { { height : 'calc(100vh - 5.5em)' , width : '100%' } } >
112- < DataGrid rows = { props . rows }
113- columns = { columns }
114- pageSize = { 5 }
115- components = { { Toolbar : AppToolbar } }
116- componentsProps = { { toolbar : { selections : selectionModel , rows : props . rows } } }
117- onSelectionModelChange = { ( model ) => setSelectionModel ( model ) }
118- selectionModel = { selectionModel }
119- rowsPerPageOptions = { [ 5 ] }
120- checkboxSelection
121- disableSelectionOnClick />
204+ { content }
122205 </ Box >
123206 </ Box >
124-
125- ) ;
126- }
127-
128- export default function App ( ) {
129- const [ token , setToken ] = useState ( "token=ABC123" ) ;
130- const [ rows , setRows ] = useState ( [ ] ) ;
131-
132- useEffect ( ( ) => {
133- const getFiles = async ( ) => {
134- let response = await fetch ( '/api/files' , {
135- method : 'POST' ,
136- headers : {
137- 'Content-Type' : 'application/text;charset=utf-8'
138- } ,
139- body : token
140- } ) ;
141- setRows ( await response . json ( ) ) ;
142- } ;
143- getFiles ( ) . catch ( console . error ) ;
144- } , [ token , setRows ] ) ;
145-
146- return (
147- < FileList rows = { rows } />
148207 ) ;
149208}
0 commit comments