Skip to content

Commit 9eb17ba

Browse files
committed
added chains dropdown in the search bar
1 parent 97bcbe5 commit 9eb17ba

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import React, { useState, useEffect, useRef } from 'react';
2+
import { NETWORK_LIST } from '@/components/common/constants';
3+
import { useRouter } from 'next/router';
4+
import { checkIfValidTerm, constructRedirectUrl } from '@/components/common/utils';
5+
import { ToastContainer, toast } from 'react-toastify';
6+
import 'react-toastify/dist/ReactToastify.css';
7+
import { LinearProgress } from '@mui/material';
8+
9+
const showToast = (toast: any, message: string) => {
10+
toast.error(message, {
11+
position: 'bottom-left',
12+
autoClose: 5000,
13+
hideProgressBar: false,
14+
closeOnClick: true,
15+
pauseOnHover: true,
16+
theme: 'colored',
17+
});
18+
};
19+
20+
const SearchBox = ({networkValue, setNetworkValue}: any) => {
21+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
22+
const [open, setOpen] = useState<boolean>(false);
23+
const [searchTerm, setSearchTerm] = useState('');
24+
const [filteredNetworks, setFilteredNetworks] = useState(NETWORK_LIST);
25+
26+
const [searching, setSearching] = useState(false);
27+
const [animateState, setAnimateState] = useState(false);
28+
const searchRef = useRef(null);
29+
const { push } = useRouter();
30+
// const [networkDropdown, setNetworkDropdown] = useState<string | null>("mainnet");
31+
32+
const handleDropdownToggle = () => {
33+
setIsDropdownOpen(!isDropdownOpen);
34+
};
35+
36+
const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
37+
setSearchTerm(e.target.value);
38+
};
39+
40+
41+
const handleValue = (index: number) => {
42+
setNetworkValue(index);
43+
44+
setIsDropdownOpen(false); // Close dropdown after selection
45+
setOpen(false);
46+
47+
};
48+
49+
const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
50+
if (e.key === 'Enter') {
51+
handleSubmit(e);
52+
}
53+
};
54+
55+
const handleSubmit = async (e?: React.FormEvent) => {
56+
if (e) e.preventDefault(); // Prevent form submission
57+
if (checkIfValidTerm(searchTerm)) {
58+
setSearching(true);
59+
try {
60+
const res = await fetch(`https://api.jiffyscan.xyz/v0/searchEntry?entry=${searchTerm.toLowerCase()}${networkValue !== -1 ? `&network=${NETWORK_LIST[networkValue].key}` : ''}`);
61+
if (res.status === 200) {
62+
const data = await res.json();
63+
console.log('API Response:', data);
64+
let redirectUrl;
65+
if (data.foundInNetwork && data.type && data.term)
66+
redirectUrl = constructRedirectUrl(data.type, data.foundInNetwork, data.term);
67+
console.log('Constructed URL:', redirectUrl);
68+
if (redirectUrl) {
69+
push(redirectUrl);
70+
} else {
71+
showToast(toast, 'No results found');
72+
}
73+
} else {
74+
showToast(toast, 'Invalid search term ?');
75+
}
76+
} catch (error) {
77+
console.error('Error:', error);
78+
showToast(toast, 'An error occurred');
79+
} finally {
80+
setSearching(false);
81+
}
82+
} else {
83+
showToast(toast, 'Invalid search term ?');
84+
}
85+
};
86+
87+
// Filter networks based on search term
88+
useEffect(() => {
89+
if (searchTerm.trim() === '') {
90+
setFilteredNetworks(NETWORK_LIST); // Reset to full list when search term is empty
91+
} else {
92+
const filtered = NETWORK_LIST.filter((network) =>
93+
network.name.toLowerCase().includes(searchTerm.toLowerCase())
94+
);
95+
setFilteredNetworks(filtered);
96+
}
97+
}, [searchTerm]);
98+
99+
return (
100+
<form className="w-full h-16">
101+
<label htmlFor="default-search" className="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">
102+
Search
103+
</label>
104+
<div className="relative">
105+
<div className="absolute inset-y-0 left-2 flex items-center ps-3 cursor-pointer" onClick={handleDropdownToggle}>
106+
<div className='flex' onClick={() => setOpen((v) => !v)}>
107+
<img src={networkValue !== -1 ? NETWORK_LIST[networkValue].iconPathInverted : "/zap2.svg"} alt="" style={{ width: '20px', height: 'auto' }} />
108+
<img className={`duration-100 ${open ? 'rotate-180' : ''}`} src="/images/chevron-down.svg" alt="" />
109+
</div>
110+
<div className="border-r-2 h-6 mx-2"></div>
111+
</div>
112+
113+
{isDropdownOpen && (
114+
<div className="absolute top-full left-0 mt-2 bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700 max-h-60 overflow-y-auto" >
115+
<div className="p-2">
116+
<input
117+
type="text"
118+
className="block w-full px-3 py-2 text-sm border border-gray-300 rounded-md dark:bg-gray-600 dark:border-gray-500"
119+
placeholder="Search Chains..."
120+
value={searchTerm}
121+
122+
/>
123+
</div>
124+
<ul className="py-2 text-sm text-gray-700 dark:text-gray-200">
125+
{filteredNetworks.map(({ name, iconPath }, index) => (
126+
<li key={index}>
127+
<a
128+
href="#"
129+
className="flex items-center gap-2 px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
130+
onClick={() => handleValue(index)}
131+
>
132+
<img src={iconPath} alt={name} className="w-5 h-5" />
133+
<span>{name}</span>
134+
</a>
135+
</li>
136+
))}
137+
</ul>
138+
</div>
139+
)}
140+
141+
<input
142+
type="search"
143+
id="default-search"
144+
className="block w-full p-4 pl-24 text-sm md:text-base font-inter text-gray-900 border border-gray-300 rounded-t-2xl bg-[#FFFFFF] focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
145+
placeholder="Search for a transaction using Transaction Id"
146+
value={searchTerm}
147+
onChange={handleSearchChange}
148+
onKeyDown={handleKeyPress}
149+
required
150+
/>
151+
152+
<p className="text-[#9E9E9E] hidden md:block border absolute right-11 bottom-3.5 bg-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg shadow-sm text-sm px-2.5 py-1 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
153+
Ctrl
154+
</p>
155+
<p className="text-[#9E9E9E] hidden md:block absolute right-4 bottom-3.5 border bg-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg shadow-sm text-sm px-2 py-1 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
156+
K
157+
</p>
158+
</div>
159+
{searching && <LinearProgress />}
160+
<ToastContainer />
161+
</form>
162+
);
163+
};
164+
165+
export default SearchBox;

0 commit comments

Comments
 (0)