Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { createFileRoute, notFound, useNavigate } from "@tanstack/react-router"
- import { useContext } from "react"
- import { PetCard } from "../../components/PetCard"
- import { Animal } from "../../types"
- import { IsDropdownClickedContext } from "../../context/IsDropdownClicked"
- import { useQuery } from "@tanstack/react-query"
- import { useDebounce } from "../../utils/useDebounce"
- type PetSearch = {
- query: string
- }
- export const Route = createFileRoute("/pets/$petCategory")({
- component: PetCategory,
- loader: async ({ params }) => {
- if (!["dogs", "cats", "birds"].includes(params.petCategory)) {
- throw notFound()
- }
- },
- validateSearch: (search: Record<string, unknown>): PetSearch => {
- return { query: search.query as string }
- },
- })
- export default function PetCategory() {
- const { petCategory } = Route.useParams()
- const { isClicked, isHidden } = useContext(IsDropdownClickedContext)
- const { query } = Route.useSearch<PetSearch>()
- const debouncedSearch = useDebounce(query)
- const navigate = useNavigate({ from: Route.fullPath })
- const {
- data: animalArray,
- isLoading,
- error,
- } = useQuery({
- queryFn: async () => {
- console.log(debouncedSearch)
- const queryToFetch = debouncedSearch ? `?search=${debouncedSearch}` : ""
- const res = await fetch(
- `https://freetestapi.com/api/v1/${petCategory}${queryToFetch}`
- )
- const data = await res.json()
- return data
- },
- queryKey: ["pets", debouncedSearch],
- })
- if (isLoading) {
- return (
- <div className="text-4xl text-white text-center my-10 uppercase">
- Loading...
- </div>
- )
- }
- if (error) {
- return (
- <div className="text-4xl text-white text-center my-10 uppercase">
- {error.message}
- </div>
- )
- }
- if(debouncedSearch === query){
- return (
- <div>
- <h1 className="text-4xl text-white text-center my-10 uppercase">
- {petCategory}
- </h1>
- <input
- type="text"
- className={`${
- isClicked && !isHidden ? "top-44" : !isHidden ? "top-20" : "top-4"
- } left-0 right-0 sticky mx-auto p-3 block mb-8 w-3/4 md:w-2/4 rounded-md `}
- placeholder={`Search through the ${petCategory} list`}
- onChange={(e) => {
- navigate({ search: (prev) => ({ ...prev, query: e.target.value }) })
- }}
- value={query}
- />
- <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 gap-y-8 w-3/4 mx-auto">
- {animalArray!.map((animal: Animal, index: number) => (
- <PetCard
- key={animal.id}
- index={index}
- animal={animal}
- animalType={petCategory!}
- />
- ))}
- </div>
- </div>
- )
- }
- }
- /// useDebounceHook
- import { useEffect, useState } from "react"
- export const useDebounce = (search: string, delay: number = 500) => {
- const [debouncedSearch, setDebouncedSearch] = useState<string>("")
- useEffect(() => {
- const delaySearch = setTimeout(() => {
- setDebouncedSearch(search)
- }, delay)
- return () => clearTimeout(delaySearch)
- }, [search])
- return debouncedSearch
- }
Advertisement
Add Comment
Please, Sign In to add comment