Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: filter for homepage and search ( for both /pets, admin/pets, and homepage) #81

Merged
merged 5 commits into from
Feb 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/admin/pets/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const Pets = () => {
}, []);

const [filters, setFilters] = useState<filterState>({
search: "",
dog: false,
cat: false,
male: false,
Expand Down Expand Up @@ -51,7 +52,7 @@ const Pets = () => {
</Container>
<Container className="flex flex-col items-center space-y-6">
<div className="flex w-full flex-row gap-x-4">
<PetSearch variant="red" />
<PetSearch variant="red" filter={filters} setFilters={setFilters} />
<div className="relative">
<PetIcon
isOpen={isOpenFilterPanel}
Expand Down
29 changes: 21 additions & 8 deletions src/app/home/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,35 @@ import Button from "@/components/Button";
import Container from "@/components/Container";
import Divider from "@/components/Divider";
import Banner from "@/components/Main/Banner";
import PetList from "@/components/Main/CardList/PetList";
import PetSuggestionList from "@/components/Main/CardList/PetSuggestionList";
import Filter from "@/components/Main/Filter";
import Heading from "@/components/Pets/Heading";
import Search from "@/components/Search/PetSearch";
import { usePetsQuery } from "@/hooks/queries/usePetsQuery";
import MainLayout from "@/layouts/MainLayout";
import { filterState } from "@/types/filter";
import { useState } from "react";
import { useNavigate } from "react-router-dom";

import PetList from "@/components/Main/CardList/PetList";
import PetSuggestionList from "@/components/Main/CardList/PetSuggestionList";

// Page
const MainPage = () => {
const navigate = useNavigate();

const { data, isLoading } = usePetsQuery();

const [filters, setFilters] = useState<filterState>({
search: "",
dog: false,
cat: false,
male: false,
female: false,
white: false,
black: false,
brown: false,
blonde: false,
minAge: 0,
maxAge: 30,
});
const { data, isLoading } = usePetsQuery(filters);
return (
<>
<Container className="grid grid-cols-1 items-center md:grid-cols-2 md:gap-9 lg:grid-cols-3">
Expand All @@ -31,8 +44,8 @@ const MainPage = () => {
<div className="hidden md:flex">
<Heading onSearch quantity={data?.metadata.total} />
</div>
<Search variant="green" />
<Filter />
<Search variant="green" filter={filters} setFilters={setFilters} />
<Filter filters={filters} setFilters={setFilters} />
</div>
</Container>
<Container className="flex items-center justify-center md:hidden">
Expand All @@ -51,7 +64,7 @@ const MainPage = () => {
<div className="col-span-2">
<PetSuggestionList
isLoading={isLoading}
data={data?.pets.slice(0, 8)}
data={data?.pets?.slice(0, 8)}
/>
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/app/pets/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const Pets = () => {
}, []);

const [filters, setFilters] = useState<filterState>({
search: "",
dog: false,
cat: false,
male: false,
Expand All @@ -41,7 +42,7 @@ const Pets = () => {
<Heading onSearch quantity={data?.metadata.total} />
</Container>
<Container className="flex flex-row gap-x-4">
<PetSearch variant="red" />
<PetSearch variant="red" filter={filters} setFilters={setFilters} />
<div className="relative">
<PetIcon
isOpen={isOpenFilterPanel}
Expand Down
57 changes: 40 additions & 17 deletions src/components/Main/Filter.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,66 @@
import Button from "@/components/Button";
import { useState } from "react";
import { filterState } from "@/types/filter";

const Filter = () => {
// There are 3 states for filtering in home search (all, dog, cat)
const [filter, setFilter] = useState<string>("all");
interface FilterProps {
filters: filterState;
setFilters: (filters: filterState) => void;
}

const Filter: React.FC<FilterProps> = ({
filters,
setFilters,
}: FilterProps) => {
const allSelected = filters.dog && filters.cat;
const catSelected = filters.cat && !filters.dog;
const dogSelected = filters.dog && !filters.cat;

return (
<div className="flex space-x-3">
<Button
text={"สัตว์เลี้ยงทั้งหมด"}
variant={filter === "all" ? "primary" : "white"}
variant={allSelected ? "primary" : "white"}
className={`flex items-center justify-center py-3 shadow transition-all duration-500
${
filter === "all"
allSelected
? "flex-row bg-primary px-6 text-white"
: "flex-col bg-white px-2.5 text-xs text-accent-gray"
} shrink-0`}
rounded="2xl"
onClick={() => setFilter("all")}
onClick={() =>
setFilters({
...filters,
dog: !allSelected,
cat: !allSelected,
})
}
/>
<Button
text={filter == "cat" ? "แมว" : ""}
variant={filter === "cat" ? "primary" : "white"}
icon={filter === "cat" ? "custom:md:cat-green" : "custom:md:cat-gray"}
text={catSelected ? "แมว" : ""}
variant={catSelected ? "primary" : "white"}
icon={catSelected ? "custom:md:cat-green" : "custom:md:cat-gray"}
className={`flex items-center justify-center space-x-2.5 py-3 shadow transition-all duration-500
${filter === "cat" ? "bg-primary px-12" : "bg-white pl-6 pr-4"}
${catSelected ? "bg-primary px-12" : "bg-white pl-6 pr-4"}
`}
rounded="2xl"
onClick={() => setFilter("cat")}
onClick={() =>
setFilters({
...filters,
dog: false,
cat: !catSelected,
})
}
/>
<Button
text={filter == "dog" ? "สุนัข" : ""}
variant={filter === "dog" ? "primary" : "white"}
icon={filter === "dog" ? "custom:md:dog-white" : "custom:md:dog-gray"}
text={dogSelected ? "สุนัข" : ""}
variant={dogSelected ? "primary" : "white"}
icon={dogSelected ? "custom:md:dog-white" : "custom:md:dog-gray"}
className={`flex items-center justify-center space-x-2.5 py-3 shadow transition-all duration-500
${filter === "dog" ? "bg-primary px-12" : "bg-white pl-6 pr-4"}
${dogSelected ? "bg-primary px-12" : "bg-white pl-6 pr-4"}
`}
rounded="2xl"
onClick={() => setFilter("dog")}
onClick={() =>
setFilters({ ...filters, dog: !dogSelected, cat: false })
}
/>
</div>
);
Expand Down
25 changes: 23 additions & 2 deletions src/components/Search/PetSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
import { filterState } from "@/types/filter";
import { Icon } from "@iconify/react";
import React from "react";
import React, { useEffect } from "react";
/*
for pets page use : @custom:md:bubble-red
for home page use: @custom:md:bubble-green
*/
interface PetSearchProps {
variant: "red" | "green";
filter: filterState;
setFilters: React.Dispatch<React.SetStateAction<filterState>>;
}

const PetSearch: React.FC<PetSearchProps> = ({ variant }) => {
const PetSearch: React.FC<PetSearchProps> = ({
variant,
filter,
setFilters,
}) => {
const [inputValue, setInputValue] = React.useState<string>(
filter.search || ""
);

// add debouce time for delay
useEffect(() => {
const delayDebounce = setTimeout(() => {
setFilters({ ...filter, search: inputValue });
}, 500);
return () => clearTimeout(delayDebounce);
}, [inputValue, setFilters, filter]);

return (
<div className="flex w-full flex-row items-center justify-start gap-3 rounded-full bg-white px-6 py-3 shadow">
<div>
Expand All @@ -18,6 +37,8 @@ const PetSearch: React.FC<PetSearchProps> = ({ variant }) => {
type="text"
placeholder="ค้นหาสัตว์เลี้ยง"
className="w-full py-0 outline-none"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions src/types/filter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
interface filterState {
search: string;
dog: boolean;
cat: boolean;
male: boolean;
Expand Down
4 changes: 4 additions & 0 deletions src/utils/convertFiltertoParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ const convertFiltertoParams = (filters?: filterState) => {
}
const params: Record<string, string | number> = {};

if (filters.search) {
params.search = filters.search;
}

if (filters.dog && filters.cat) {
// skip
} else if (filters.dog) {
Expand Down
Loading