Last active
June 9, 2023 13:29
-
-
Save squashfold/c0a59cf84de0d62b48d98e3076784880 to your computer and use it in GitHub Desktop.
Show search results in NextJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Head from 'next/head'; | |
import { useCallback, useRef, useState, useEffect } from 'react' | |
import type Post from '../../interfaces/post' | |
import PostPreview from '../../components/post-preview' | |
export default function Home() { | |
const searchRef = useRef<HTMLInputElement>(null) | |
const defaultPosts = require('../../cache/data/posts').data; // We want to show all posts by default | |
const [query, setQuery] = useState('') | |
const [results, setResults] = useState<any[]>(defaultPosts) | |
const searchEndpoint = (query: string) => `/api/search?query=${query}` | |
const getResults = (query: string) => { | |
if (query.length) { | |
fetch(searchEndpoint(query)) | |
.then(res => res.json()) | |
.then(res => { | |
setResults(res.results.map((element) => element.item)) // Fuzzy search returns our results in a different format | |
}) | |
.catch(error => { | |
console.error('Error fetching search results:', error) | |
setResults([]) | |
}) | |
} else { | |
setResults(defaultPosts) | |
} | |
}; | |
const onChange = useCallback((event) => { | |
const query = event.target.value; | |
setQuery(query) | |
}, [query]) | |
useEffect(() => { | |
getResults(query); | |
}, [query]); | |
return ( | |
<> | |
<Head> | |
<title>{`Search`}</title> | |
</Head> | |
<div className={`container mx-auto px-5`}> | |
<h1 className={`text-5xl md:text-8xl font-bold tracking-tighter leading-tight md:pr-8`}>Search Articles</h1> | |
<div ref={searchRef} className={`mb-4`}> | |
<div> | |
<label htmlFor="searchInput" className={`mr-4`}>Filter:</label> | |
<input | |
className={`p-2 border-solid border-2 border-black`} | |
onChange={onChange} | |
placeholder='Search posts' | |
type='text' | |
value={query} | |
id="searchInput" | |
/> | |
</div> | |
</div> | |
<div className={`grid grid-cols-3 gap-4`}> | |
{results.length ? | |
<> | |
{results.map((post: Post, index) => ( | |
<PostPreview | |
key={post.slug} | |
title={post.title} | |
coverImage={post.coverImage} | |
date={post.date} | |
author={post.author} | |
slug={post.slug} | |
excerpt={post.excerpt} | |
/> | |
))} | |
</> | |
: | |
<> | |
<p>No results found...</p> | |
</> | |
} | |
</div> | |
</div> | |
</> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment