Skip to content

Commit c236ae7

Browse files
authored
Merge pull request #116 from ctfguide-tech/feat-search-frontend
Introduce new Search UI/UX into dev.
2 parents 47fda0f + 2de234d commit c236ae7

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

.env.development

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
#NEXT_PUBLIC_APP_ID=1:166652277588:web:e08b9e19916451e14dcec1
1010
#NEXT_PUBLIC_APP_MEASUREMENT_ID=G-7ZNKM9VFN2
1111

12-
# TDO
13-
1412
NEXT_PUBLIC_API_URL=http://localhost:3001
1513
NEXT_PUBLIC_FRONTEND_URL=http://localhost:3000
1614
NEXT_PUBLIC_APP_API_KEY=AIzaSyAHz1s-UuNhlZ6aKvqwzmzzidzWxBKw9hw

src/components/nav/SearchModal.jsx

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
import React from 'react';
22
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
33
import { faSearch, faBug, faLock, faUserSecret, faNetworkWired, faBrain, faTerminal } from '@fortawesome/free-solid-svg-icons';
4+
import { useState, useEffect } from 'react';
5+
import request from '@/utils/request';
6+
import {useRouter} from 'next/router';
47

58
const SearchModal = ({ showSearchModal, setShowSearchModal }) => {
9+
const [search, setSearch] = useState('');
10+
const [results, setResults] = useState(null);
11+
const router = useRouter();
12+
const debouncedSearchTerm = useDebounce(search, 100); // 300ms delay
13+
14+
useEffect(() => {
15+
if (debouncedSearchTerm) {
16+
const endpoint = process.env.NEXT_PUBLIC_API_URL;
17+
const url = `${endpoint}/search/${debouncedSearchTerm}`;
18+
console.log(url);
19+
request(url, "GET", null).then((res) => {
20+
setResults(res.results);
21+
console.log(res);
22+
}).catch((err) => { console.log(err); });
23+
}
24+
}, [debouncedSearchTerm]);
25+
26+
const routeToChallenge = (id) => router.push("/challenges/"+id);
27+
const routeToUser = (username) => router.push("/users/"+username);
28+
629
return (
730
<>
831
{showSearchModal && (
@@ -19,8 +42,31 @@ const SearchModal = ({ showSearchModal, setShowSearchModal }) => {
1942
<div className="px-4 py-5 sm:px-6 mx-auto">
2043
<div className='flex items-center mx-auto'>
2144
<FontAwesomeIcon icon={faSearch} className="w-5 h-5 mr-1 text-white" />
22-
<input placeholder="Search for challenges, users, or competitions" className='w-full border-0 text-xl focus:ring-0 bg-transparent text-white' autoFocus />
45+
<input onChange={e => {
46+
setSearch(e.target.value)
47+
if(e.target.value === '') setResults(null);
48+
}} placeholder="Search for challenges, users, or competitions" className='w-full border-0 text-xl focus:ring-0 bg-transparent text-white' autoFocus />
2349
</div>
50+
51+
{
52+
results && search && (
53+
<div className='mt-5'>
54+
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4'>
55+
{results.challenges.map((result, index) => (
56+
<div style={{cursor: "pointer"}} key={index} className='p-3 bg-neutral-700 rounded-lg' onClick={() => routeToChallenge(result.id)}>
57+
<h1 className='text-md text-white font-semibold'>{result.title}</h1>
58+
</div>
59+
))}
60+
{results.users.map((result, index) => (
61+
<div style={{cursor: "pointer"}} key={index} className='p-3 bg-neutral-700 rounded-lg' onClick={() => routeToUser(result.username)}>
62+
<h1 className='text-md text-white font-semibold'>{result.username}</h1>
63+
</div>
64+
))}
65+
</div>
66+
</div>
67+
)
68+
}
69+
2470
<h1 className='mt-10 text-xl text-white font-semibold mb-4'>Search by Category</h1>
2571
<div className="flex flex-wrap gap-2">
2672
<button className="px-4 py-2 rounded bg-blue-500 bg-opacity-50 border border-blue-800 hover:brightness-110 text-white flex items-center gap-2">
@@ -58,4 +104,20 @@ const SearchModal = ({ showSearchModal, setShowSearchModal }) => {
58104
);
59105
};
60106

107+
function useDebounce(value, delay) {
108+
const [debouncedValue, setDebouncedValue] = useState(value);
109+
110+
useEffect(() => {
111+
const handler = setTimeout(() => {
112+
setDebouncedValue(value);
113+
}, delay);
114+
115+
return () => {
116+
clearTimeout(handler);
117+
};
118+
}, [value, delay]);
119+
120+
return debouncedValue;
121+
}
122+
61123
export default SearchModal;

src/pages/login.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ export default function Login() {
5050

5151
// do the same for google auth login
5252
async function handleSuccess(data) {
53-
console.log("Setting account by google");
5453
const { credential } = data;
5554
const decode = jwtDecode(credential);
5655
const { email } = decode;

0 commit comments

Comments
 (0)