Skip to content

Commit afbc5b2

Browse files
committed
Semifunctional search bar
1 parent 4a894a6 commit afbc5b2

File tree

2 files changed

+53
-20
lines changed

2 files changed

+53
-20
lines changed

explorer/src/lib/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export interface CoinSpendsResponse {
112112
}
113113

114114
export async function getBlocks() {
115-
const response = await get<BlocksResponse>('/blocks?reverse=true&limit=50');
115+
const response = await get<BlocksResponse>('/blocks?reverse=true&limit=15');
116116
return response.blocks;
117117
}
118118

explorer/src/pages/Home.tsx

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
TooltipContent,
66
TooltipTrigger,
77
} from '@/components/ui/tooltip';
8-
import { BlockRecord, getBlocks } from '@/lib/api';
8+
import { BlockRecord, getBlock, getBlockByHeight, getBlocks } from '@/lib/api';
99
import { MAX_BLOCK_COST } from '@/lib/constants';
1010
import { truncateHash } from '@/lib/conversions';
1111
import { intlFormat, intlFormatDistance } from 'date-fns';
@@ -16,34 +16,67 @@ import { Link } from 'react-router-dom';
1616
export function Home() {
1717
const [blocks, setBlocks] = useState<BlockRecord[]>([]);
1818
const [search, setSearch] = useState('');
19+
const [searchResult, setSearchResult] = useState<BlockRecord | null>(null);
20+
const [error, setError] = useState<string | null>(null);
1921

2022
useEffect(() => {
2123
getBlocks().then(setBlocks);
2224
}, []);
2325

26+
const handleSearch = async (value: string) => {
27+
setSearch(value);
28+
setError(null);
29+
30+
if (!value) {
31+
setSearchResult(null);
32+
return;
33+
}
34+
35+
try {
36+
let block: BlockRecord | null = null;
37+
38+
// Try parsing as block height first
39+
const height = parseInt(value);
40+
if (!isNaN(height) && height < 2 ** 32) {
41+
block = await getBlockByHeight(height);
42+
} else {
43+
// If not a number, try as header hash
44+
block = await getBlock(value);
45+
}
46+
47+
if (block) {
48+
setSearchResult(block);
49+
} else {
50+
setError('Block not found');
51+
}
52+
} catch {
53+
setError('Failed to fetch block');
54+
}
55+
};
56+
57+
const displayedBlocks = searchResult ? [searchResult] : blocks;
58+
2459
return (
2560
<Layout>
26-
<div className='flex items-center justify-between mb-6'>
27-
<h1 className='text-3xl font-semibold'>Recent Blocks</h1>
28-
<Input
29-
className='w-80'
30-
placeholder='Search by height or hash...'
31-
value={search}
32-
onChange={(e) => setSearch(e.target.value)}
33-
/>
61+
<div className='flex flex-col md:flex-row md:items-center justify-between gap-4 mb-6'>
62+
<h1 className='text-3xl font-semibold'>
63+
{searchResult ? 'Search Result' : 'Recent Blocks'}
64+
</h1>
65+
<div className='w-full md:w-80 space-y-2'>
66+
<Input
67+
className='w-full'
68+
placeholder='Search by height or hash...'
69+
value={search}
70+
onChange={(e) => handleSearch(e.target.value)}
71+
/>
72+
{error && <div className='text-sm text-red-500'>{error}</div>}
73+
</div>
3474
</div>
3575

3676
<div className='grid gap-2'>
37-
{blocks
38-
.filter(
39-
(block) =>
40-
search === '' ||
41-
block.height.toString().includes(search) ||
42-
block.header_hash.toLowerCase().includes(search.toLowerCase()),
43-
)
44-
.map((block) => (
45-
<Block key={block.height} block={block} />
46-
))}
77+
{displayedBlocks.map((block) => (
78+
<Block key={block.height} block={block} />
79+
))}
4780
</div>
4881
</Layout>
4982
);

0 commit comments

Comments
 (0)