Skip to content

Commit 23860d5

Browse files
committed
Fix broken search form
1 parent 724b125 commit 23860d5

File tree

5 files changed

+134
-144
lines changed

5 files changed

+134
-144
lines changed

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@
1414
"dependencies": {
1515
"@fortawesome/fontawesome-free": "^5.15.1",
1616
"bulma": "^0.9.1",
17-
"react": "^17.0.0",
18-
"react-dom": "^17.0.0",
19-
"react-window": "^1.8.6",
17+
"react": "^16.0.0",
18+
"react-dom": "^16.0.0",
19+
"react-fluid-table": "^0.4.2",
2020
"tslib": "^2.0.3",
21-
"window-table": "^1.0.0-alpha.11"
21+
"use-http": "^1.0.26"
2222
},
2323
"devDependencies": {
2424
"@types/node": "^16.0.0",
25-
"@types/react": "^17.0.0",
26-
"@types/react-dom": "^17.0.0",
25+
"@types/react": "^16.0.0",
26+
"@types/react-dom": "^16.0.0",
2727
"copy-webpack-plugin": "^9.0.0",
2828
"css-loader": "^6.4.0",
2929
"file-loader": "^6.2.0",

src/banks.tsx

+32-56
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
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";
42
import { useSearchContext } from "./searchContext";
3+
import { Table } from "react-fluid-table";
4+
import useFetch from 'use-http';
5+
import { Loading } from "./loading";
56

67
interface BankData {
78
readonly code: string;
@@ -11,51 +12,24 @@ interface BankData {
1112
readonly roma: string;
1213
}
1314

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-
3515
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])
5933

6034
return (
6135
<div className="section">
@@ -66,25 +40,27 @@ export const Banks: FunctionComponent = () => {
6640
type="search"
6741
className="input"
6842
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)}
7145
/>
7246
<span className="icon is-left">
7347
<i className="fas fa-search" />
7448
</span>
7549
</div>
7650
</div>
7751
</form>
78-
<Html5Table
52+
{ error ? <div>{error.message}</div> : null }
53+
{ loading ? <Loading message="loading banks..." /> : null }
54+
{ banks.length > 0 && <Table
7955
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' },
8258
]}
83-
data={banks}
59+
data={filteredBanks}
60+
tableHeight={300}
8461
className="is-fullwidth"
85-
style={{ height: 'min(30rem,100vh)', overflow: 'hidden' }}
86-
Row={Row}
87-
/>
62+
onRowClick={onRowClick}
63+
/> }
8864
<div className="notification is-info is-light mt-3">
8965
<p>This data by <a href="/api/banks.json">https://zengin-code.github.io/api/banks.json</a> .</p>
9066
<p>You can use this JSON like API.</p>

src/branches.tsx

+22-44
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import React, { FunctionComponent, useEffect, useState } from "react";
2-
import { Html5Table, useDebouncedState, createFilter, useFilter } from 'window-table';
1+
import React, { FunctionComponent, useState } from "react";
2+
import { Table } from "react-fluid-table";
3+
import useFetch from "use-http";
34
import { Loading } from "./loading";
45

56
interface BranchData {
@@ -10,48 +11,25 @@ interface BranchData {
1011
readonly roma: string;
1112
}
1213

13-
interface State {
14-
loading: boolean;
15-
branches: BranchData[];
16-
invalid: boolean;
17-
}
18-
19-
const filter = createFilter(['code', 'name', 'kana', 'hira', 'roma'])
20-
2114
export const Branches: FunctionComponent<{ code: string }> = ({ code }) => {
22-
const [state, change] = useState<State>({ loading: false, invalid: true, branches: [] });
23-
const [text, debouncedText, setText] = useDebouncedState('');
24-
25-
useEffect(() => {
26-
if (!code) {
27-
change({ ...state, loading: false, branches: [], invalid: true });
28-
return
15+
const [ state, update ] = useState('');
16+
const { loading, error, data } = useFetch<Record<string,BranchData>>(`/api/branches/${code}.json`, {}, [code])
17+
const branches = data ? Object.values(data).sort((a, b) => parseInt(a.code, 10) - parseInt(b.code, 10)) : [];
18+
const filteredBranches = branches.filter((branch) => {
19+
if (state) {
20+
return Object.values(branch).reduce((match, field) => match || field.includes(state), false);
21+
} else {
22+
return true;
2923
}
24+
})
3025

31-
change({ ...state, loading: true, invalid: false });
32-
33-
fetch(`/api/branches/${code}.json`)
34-
.then((res) => res.json())
35-
.then((branches: { [key: string]: BranchData}) => {
36-
return Object.values(branches).sort((a, b) => parseInt(a.code, 10) - parseInt(b.code, 10))
37-
})
38-
.then((branches) => {
39-
change({ ...state, branches, loading: false, invalid: false });
40-
})
41-
.catch(() => {
42-
change({ ...state, loading: false, invalid: true });
43-
});
44-
}, [code])
45-
46-
const branches = useFilter(filter, state.branches, debouncedText) as BranchData[];
47-
48-
if (state.loading) {
26+
if (loading) {
4927
return <Loading message="Loading branches..." />;
5028
}
5129

5230
return (
5331
<div className="section">
54-
{state.invalid ? (
32+
{error ? (
5533
<div className="notification has-text-centered">
5634
<p>Select a bank</p>
5735
</div>
@@ -64,24 +42,24 @@ export const Branches: FunctionComponent<{ code: string }> = ({ code }) => {
6442
type="search"
6543
className="input"
6644
placeholder="ex: 0001 or ginza or ぎんざ or 銀座"
67-
value={text}
68-
onChange={(e) => setText(e.target.value)}
45+
value={state}
46+
onChange={(e) => update(e.target.value)}
6947
/>
7048
<span className="icon is-left">
7149
<i className="fas fa-search" />
7250
</span>
7351
</div>
7452
</div>
7553
</form>
76-
<Html5Table
54+
{data && <Table
7755
columns={[
78-
{ key: 'code', title: 'Code', width: 1 },
79-
{ key: 'name', title: 'Name', width: 2 },
56+
{ key: 'code', header: 'Code', width: 120 },
57+
{ key: 'name', header: 'Name' },
8058
]}
81-
data={branches}
59+
data={filteredBranches}
8260
className="is-fullwidth"
83-
style={{ height: 'min(30rem,100vh)', overflow: 'hidden' }}
84-
/>
61+
tableHeight={300}
62+
/>}
8563
<div className="notification is-info is-light mt-3">
8664
<p>This data by <a href={`/api/branches/${code}.json`}>https://zengin-code.github.io/api/branches/{code}.json</a> .</p>
8765
<p>You can use this JSON like API.</p>

src/search.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { SearchContextProvider } from "./searchContext";
66
export const Search: FunctionComponent = () => {
77
const [state, update] = useState({ code: '' });
88
const { code } = state;
9-
const change = useCallback((code: string) => update({ code }), [update])
9+
const change = useCallback((code: string) => {
10+
update(() => ({ code }))
11+
}, [update])
1012

1113
return (
1214
<SearchContextProvider value={{ code, change }}>

0 commit comments

Comments
 (0)