1
- import React , { FunctionComponent , HTMLAttributes , useEffect , useState } from "react" ;
2
- import { Html5Table , useDebouncedState , createFilter , useFilter } from 'window-table' ;
3
- import { Loading } from "./loading" ;
1
+ import React , { FunctionComponent , useCallback , useState } from "react" ;
4
2
import { useSearchContext } from "./searchContext" ;
3
+ import { Table } from "react-fluid-table" ;
4
+ import useFetch from 'use-http' ;
5
+ import { Loading } from "./loading" ;
5
6
6
7
interface BankData {
7
8
readonly code : string ;
@@ -11,51 +12,24 @@ interface BankData {
11
12
readonly roma : string ;
12
13
}
13
14
14
- interface State {
15
- loading : boolean ;
16
- banks : BankData [ ] ;
17
- }
18
-
19
- const filter = createFilter ( [ 'code' , 'name' , 'kana' , 'hira' , 'roma' ] )
20
-
21
- const Row : FunctionComponent < HTMLAttributes < HTMLTableRowElement > & { row : BankData } > = ( { row, className, ...props } ) => {
22
- const ctx = useSearchContext ( ) ;
23
-
24
- return (
25
- < tr
26
- { ...props }
27
- onClick = { ( ) => {
28
- ctx . change ( row . code ) ;
29
- } }
30
- className = { `${ className } ${ row . code === ctx . code ? 'is-selected' : '' } ` }
31
- />
32
- ) ;
33
- }
34
-
35
15
export const Banks : FunctionComponent = ( ) => {
36
- const [ state , change ] = useState < State > ( { loading : false , banks : [ ] } ) ;
37
- const [ text , debouncedText , setText ] = useDebouncedState ( '' ) ;
38
-
39
- useEffect ( ( ) => {
40
- change ( { ...state , loading : true } ) ;
41
- fetch ( '/api/banks.json' )
42
- . then ( ( res ) => res . json ( ) )
43
- . then ( ( banks : { [ key : string ] : BankData } ) => {
44
- return Object . values ( banks ) . sort ( ( a , b ) => parseInt ( a . code , 10 ) - parseInt ( b . code , 10 ) )
45
- } )
46
- . then ( ( banks ) => {
47
- change ( { ...state , banks, loading : false } )
48
- } )
49
- . catch ( ( ) => {
50
- change ( { ...state , loading : false } ) ;
51
- } )
52
- } , [ ] )
53
-
54
- const banks = useFilter ( filter , state . banks , debouncedText ) as BankData [ ] ;
55
-
56
- if ( state . loading ) {
57
- return < Loading message = "Loading banks..." /> ;
58
- }
16
+ const ctx = useSearchContext ( ) ;
17
+ const [ state , update ] = useState ( '' ) ;
18
+ const { loading, error, data } = useFetch < Record < string , BankData > > ( '/api/banks.json' , { } , [ ] ) ;
19
+ const banks = data ? Object . values ( data ) . sort ( ( a , b ) => parseInt ( a . code , 10 ) - parseInt ( b . code , 10 ) ) : [ ] ;
20
+ const filteredBanks = banks . filter ( ( bank ) => {
21
+ if ( state ) {
22
+ return Object . values ( bank ) . reduce ( ( match , field ) => match || field . includes ( state ) , false ) ;
23
+ } else {
24
+ return true ;
25
+ }
26
+ } )
27
+ const onRowClick = useCallback ( ( _ , { index } ) => {
28
+ const bank = filteredBanks [ index ] ;
29
+ if ( bank ) {
30
+ ctx . change ( bank . code )
31
+ }
32
+ } , [ ctx . change , filteredBanks ] )
59
33
60
34
return (
61
35
< div className = "section" >
@@ -66,25 +40,27 @@ export const Banks: FunctionComponent = () => {
66
40
type = "search"
67
41
className = "input"
68
42
placeholder = "ex: 0005 or みつびし or mitsubishi or 三菱"
69
- value = { text }
70
- onChange = { ( e ) => setText ( e . target . value ) }
43
+ value = { state }
44
+ onChange = { ( e ) => update ( e . target . value ) }
71
45
/>
72
46
< span className = "icon is-left" >
73
47
< i className = "fas fa-search" />
74
48
</ span >
75
49
</ div >
76
50
</ div >
77
51
</ form >
78
- < Html5Table
52
+ { error ? < div > { error . message } </ div > : null }
53
+ { loading ? < Loading message = "loading banks..." /> : null }
54
+ { banks . length > 0 && < Table
79
55
columns = { [
80
- { key : 'code' , title : 'Code' , width : 1 } ,
81
- { key : 'name' , title : 'Name' , width : 2 } ,
56
+ { key : 'code' , header : 'Code' , width : 120 } ,
57
+ { key : 'name' , header : 'Name' } ,
82
58
] }
83
- data = { banks }
59
+ data = { filteredBanks }
60
+ tableHeight = { 300 }
84
61
className = "is-fullwidth"
85
- style = { { height : 'min(30rem,100vh)' , overflow : 'hidden' } }
86
- Row = { Row }
87
- />
62
+ onRowClick = { onRowClick }
63
+ /> }
88
64
< div className = "notification is-info is-light mt-3" >
89
65
< p > This data by < a href = "/api/banks.json" > https://zengin-code.github.io/api/banks.json</ a > .</ p >
90
66
< p > You can use this JSON like API.</ p >
0 commit comments