DEV Community

San
San

Posted on

URL Params value change on select using next js 13

"use client";
import { searchFilterProductAPI } from "@/utils";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import React, { useEffect, useState } from "react";

// const checkList = ["Apple", "Banana", "Tea", "Coffee"];
const checkList = ["All", "Michael Kors", "Tommy Hilfiger", "Emporio Armani"];

interface MyFilterProps {
  brands: any;
}

const MyFilter = ({ brands }: MyFilterProps) => {
  const searchParams = useSearchParams();
  const pathname = usePathname();
  const router = useRouter();
  const [checkedItems, setCheckedItems] = useState<any>([]);
  const [catsItems, setCatsItems] = useState<any>([]);
  const [selectedPrice, setSelectedPrice] = useState("");
  const [searchTerm, setSearchTerm] = useState<any>("watch");

  function handleBrandChage(e: any) {
    const { value, checked } = e.target;
    let isSelected = checked;
    if (isSelected) {
      setCheckedItems([...checkedItems, value]);
    } else {
      setCheckedItems((preItems: any) => {
        return preItems?.filter((val: any) => {
          return val !== value;
        });
      });
    }
  }

  function handleCatsChage(e: any) {
    const { value, checked } = e.target;
    const selectedVal = value;
    let isSelected = checked;
    if (isSelected) {
      setCatsItems([...catsItems, selectedVal]);
    } else {
      setCatsItems((preItems: any) => {
        return preItems?.filter((val: any) => {
          return val !== selectedVal;
        });
      });
    }
  }

  // handle price select
  const handlePriceSelect = (e: any) => {
    const { value } = e.target;
    setSelectedPrice(value);
  };

  const params = new URLSearchParams(searchParams);
  // const searchTerm = "watch";
  useEffect(() => {
    if (searchTerm) {
      params.set("q", searchTerm);
    } else {
      params.delete("q");
    }
    if (!checkedItems || !catsItems) {
      params.set("", "");
      return;
    }
    if (checkedItems) {
      params.set("brand", checkedItems);
      router.push(`${pathname}?${params}`);
    } else {
      params.delete("brand", "");
    }
  }, [checkedItems]);

  console.log("checkedItems=>", { checkedItems, catsItems });

  useEffect(() => {
    if (catsItems) {
      params.set("category", catsItems);
      router.push(`${pathname}?${params}`);
    } else {
      params.delete("category", "");
    }
    if (selectedPrice) {
      params.set("price", selectedPrice);
      router.push(`${pathname}?${params}`);
    } else {
      params.delete("price", "");
    }
  }, [catsItems, selectedPrice]);

  // useEffect(() => {
  //   if (selectedPrice) {
  //     params.set("price", selectedPrice);
  //     router.push(`${pathname}?${params}`);
  //   } else {
  //     params.delete("price", "");
  //   }
  // }, [selectedPrice]);

  // API call for search and filter
  const category = catsItems.toString();
  const brand = checkedItems.toString();
  useEffect(() => {
    const q: any = "watch";
    const searchFilterProduct = async () => {
      await searchFilterProductAPI(searchTerm, category, brand, selectedPrice);
    };
    if (searchTerm) {
      searchFilterProduct();
    }
  }, [searchTerm, checkedItems, catsItems, selectedPrice]);

  const clearAllFilter = async () => {
    // setSearchTerm("");
    setSelectedPrice("");
    setCheckedItems("");
    setCatsItems("");
    await searchFilterProductAPI(searchTerm, category, brand, selectedPrice);
    router.push(`${pathname}?q=${searchTerm}`);
    router.refresh();
  };

  // console.log("selectedPrice==>", selectedPrice);

  return (
    <>
      <button onClick={clearAllFilter}>Clear Filter</button>
      <h1>Brand Filter</h1>
      {checkList &&
        checkList?.map((b: any, i: number) => (
          <>
            <input
              key={b}
              type="checkbox"
              checked={checkedItems?.includes(b)}
              value={b}
              onChange={handleBrandChage}
              name="brand-checkbox"
            />
            <label> {b}</label>
            <br />
          </>
        ))}
      <div className="result">
        Above checkbox is {checkedItems && checkedItems.join(", ")}.
      </div>

      <h1>category Filter</h1>
      {brands &&
        brands?.map((b: any) => (
          <>
            <input
              key={b.id}
              type="checkbox"
              checked={catsItems?.includes(b.brand)}
              value={b.brand}
              onChange={handleCatsChage}
              name="brand-checkbox"
            />
            <label> {b.brand}</label>
            <br />
          </>
        ))}
      <div className="result">
        Above checkbox is {catsItems && catsItems.join(", ")}.
      </div>

      {/* Price set */}
      <label
        htmlFor="price"
        className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
      >
        Select price range
      </label>
      <select
        defaultValue="nan"
        className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 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"
        onChange={handlePriceSelect}
      >
        <option defaultValue={selectedPrice}>
          {selectedPrice === "" && "Choose a country"}
        </option>
        <option value="500">Above 500</option>
        <option value="2000">Above 2000</option>
        <option value="5000">Above 5000</option>
        <option value="10000">Above 10000</option>
        <option value="20000">Above 20000</option>
        <option value="30000">Above 30000</option>
        <option value="40000">Above 40000</option>
        <option value="50000">Above 50000</option>
      </select>
    </>
  );
};

export default MyFilter;

Enter fullscreen mode Exit fullscreen mode

2. server-side search and filter

export async function searchFilterProductAPI(q: string, category: string, brand: string, price: string) {
  console.log('searchFilterProductAPI', { q, category, brand, price });
  // http://103.174.102.250:3000/api/filter?q=watch&category=Women's Watch&brand=Tommy Hilfiger&price
  try {
    const res = await axios.get(`${apiUrl}/filter?q=${q}&category=${category}&brand=${brand}&price=${price}`);
    const data = await res.data
    console.log('result api=?', data);
    return data;

  } catch (err) {
    console.log('err occured==>', err);
  }
};
Enter fullscreen mode Exit fullscreen mode

Top comments (0)