mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 20:13:49 +00:00
This commit adds the necessary components and hooks to implement a beer search feature on the website. It includes the following changes: - Add a new BeerSearch API route that returns a list of beers matching a search query. - Implement a new hook useBeerPostSearch that utilizes SWR to fetch data from the API and parse it using a schema. - Add a new page SearchPage that displays a search input field and a list of beer search results. - Use lodash's debounce function to avoid making too many requests while the user is typing in the search input field.
58 lines
1.8 KiB
TypeScript
58 lines
1.8 KiB
TypeScript
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
|
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
|
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
|
import { NextApiRequest, NextApiResponse } from 'next';
|
|
import { createRouter } from 'next-connect';
|
|
import { z } from 'zod';
|
|
import DBClient from '@/prisma/DBClient';
|
|
import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult';
|
|
|
|
const SearchSchema = z.object({
|
|
search: z.string().min(1),
|
|
});
|
|
|
|
interface SearchAPIRequest extends NextApiRequest {
|
|
query: z.infer<typeof SearchSchema>;
|
|
}
|
|
|
|
const search = async (req: SearchAPIRequest, res: NextApiResponse) => {
|
|
const { search: query } = req.query;
|
|
|
|
const beers: BeerPostQueryResult[] = await DBClient.instance.beerPost.findMany({
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
ibu: true,
|
|
abv: true,
|
|
createdAt: true,
|
|
description: true,
|
|
postedBy: { select: { username: true, id: true } },
|
|
brewery: { select: { name: true, id: true } },
|
|
type: { select: { name: true, id: true } },
|
|
beerImages: { select: { alt: true, path: true, caption: true, id: true } },
|
|
},
|
|
where: {
|
|
OR: [
|
|
{ name: { contains: query, mode: 'insensitive' } },
|
|
{ description: { contains: query, mode: 'insensitive' } },
|
|
|
|
{ brewery: { name: { contains: query, mode: 'insensitive' } } },
|
|
{ type: { name: { contains: query, mode: 'insensitive' } } },
|
|
],
|
|
},
|
|
});
|
|
|
|
res.status(200).json(beers);
|
|
};
|
|
|
|
const router = createRouter<
|
|
SearchAPIRequest,
|
|
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
|
>();
|
|
|
|
router.get(validateRequest({}), search);
|
|
|
|
const handler = router.handler(NextConnectOptions);
|
|
|
|
export default handler;
|