Witaj,{user}
diff --git a/src/components/ui/searchbar.tsx b/src/components/ui/searchbar.tsx
index c35a479..8f2791b 100644
--- a/src/components/ui/searchbar.tsx
+++ b/src/components/ui/searchbar.tsx
@@ -3,13 +3,25 @@ import Button from "../utilities/button";
import Icon from "../../lib/iconConfig";
import { CustomClasses } from "../utilities/customClasses";
-export default function SearchBar() {
+export default function SearchBar({
+ search,
+ setSearch,
+}: {
+ search: string;
+ setSearch: (search: string) => void;
+}) {
return (
-
+ setSearch(event.target.value)}
+ className={cn("border-none outline-none m-1 ml-2 w-full text-xs")}
+ />
);
-}
\ No newline at end of file
+}
diff --git a/src/components/ui/sideBar.tsx b/src/components/ui/sideBar.tsx
index 1fdfee8..59ed4f7 100644
--- a/src/components/ui/sideBar.tsx
+++ b/src/components/ui/sideBar.tsx
@@ -4,7 +4,17 @@ import Filters from "./filters";
import Icon from "../../lib/iconConfig";
import Button from "../utilities/button";
-export default function SideBar() {
+export default function SideBar({
+ categories,
+ selectedCategory,
+ setSelectedCategory,
+ clearFilters,
+}: {
+ categories: string[];
+ selectedCategory: string;
+ setSelectedCategory: (category: string) => void;
+ clearFilters: () => void;
+}) {
return (
@@ -17,12 +27,16 @@ export default function SideBar() {
-
+
-
+
);
-}
\ No newline at end of file
+}
diff --git a/src/components/utilities/filter.tsx b/src/components/utilities/filter.tsx
index 9091fa5..528d44a 100644
--- a/src/components/utilities/filter.tsx
+++ b/src/components/utilities/filter.tsx
@@ -2,7 +2,17 @@ import { cn } from "../../lib/utils";
import Icon from "../../lib/iconConfig";
import { CustomClasses } from "./customClasses";
-export function Filter({name, items}: {name: string, items: string[]}) {
+export function Filter({
+ name,
+ items,
+ selectedItem,
+ setSelectedItem,
+}: {
+ name: string;
+ items: string[];
+ selectedItem: string;
+ setSelectedItem: (item: string) => void;
+}) {
return (
@@ -16,7 +26,12 @@ export function Filter({name, items}: {name: string, items: string[]}) {
{items.map((item, index) => (
@@ -24,4 +39,4 @@ export function Filter({name, items}: {name: string, items: string[]}) {
);
-}
\ No newline at end of file
+}
diff --git a/src/hooks/useTableFilters.ts b/src/hooks/useTableFilters.ts
new file mode 100644
index 0000000..dc052f0
--- /dev/null
+++ b/src/hooks/useTableFilters.ts
@@ -0,0 +1,48 @@
+import { useSearchParams } from "react-router-dom";
+
+export function useTableFilters() {
+ const [params, setParams] = useSearchParams();
+
+ const page = Math.max(1, Math.floor(Number(params.get("page")) || 1));
+ const search = params.get("search") ?? "";
+ const category = params.get("category") ?? "";
+
+ const updateParam = (key: "search" | "page" | "category", value: string) => {
+ setParams((currentParams) => {
+ const nextParams = new URLSearchParams(currentParams);
+ const nextValue = value.trim();
+
+ if (!nextValue || (key === "page" && nextValue === "1")) {
+ nextParams.delete(key);
+ } else {
+ nextParams.set(key, nextValue);
+ }
+
+ if (key !== "page") {
+ nextParams.delete("page");
+ }
+
+ return nextParams;
+ });
+ };
+
+ return {
+ page,
+ search,
+ category,
+ setPage: (nextPage: number) => updateParam("page", String(nextPage)),
+ setSearch: (nextSearch: string) => updateParam("search", nextSearch),
+ setCategory: (nextCategory: string) => updateParam("category", nextCategory),
+ clearFilters: () => {
+ setParams((currentParams) => {
+ const nextParams = new URLSearchParams(currentParams);
+
+ nextParams.delete("search");
+ nextParams.delete("page");
+ nextParams.delete("category");
+
+ return nextParams;
+ });
+ },
+ };
+}
diff --git a/src/pages/layout.tsx b/src/pages/layout.tsx
index 321f9d5..696a537 100644
--- a/src/pages/layout.tsx
+++ b/src/pages/layout.tsx
@@ -9,28 +9,59 @@ import { CustomClasses } from "../components/utilities/customClasses";
import EditForm from "../components/ui/editForm";
import { mockedProducts } from "../api/mockeddata";
import TableNavigation from "../components/ui/tableNavigation";
-import { useState } from "react";
+import { useEffect, useMemo, useState } from "react";
+import { useTableFilters } from "../hooks/useTableFilters";
export default function Layout() {
const [isEditFormOpen, setIsEditFormOpen] = useState(false);
- const [currentPage, setCurrentPage] = useState(1);
+ const tableFilters = useTableFilters();
function handleSetCurrentPage(page: number) {
if (page < 1) {
- setCurrentPage(1);
+ tableFilters.setPage(1);
} else if (page > pages) {
- setCurrentPage(pages);
+ tableFilters.setPage(pages);
} else {
- setCurrentPage(page);
+ tableFilters.setPage(page);
}
}
const itemsPerPage = 7;
- const pages = Math.ceil(mockedProducts.length / itemsPerPage);
+ const categories = useMemo(
+ () => Array.from(new Set(mockedProducts.map((product) => product.category))),
+ [],
+ );
+ const filteredProducts = useMemo(() => {
+ const search = tableFilters.search.toLowerCase();
+
+ return mockedProducts.filter((product) => {
+ const matchesCategory =
+ !tableFilters.category || product.category === tableFilters.category;
+ const matchesSearch =
+ !search ||
+ product.productName.toLowerCase().includes(search) ||
+ product.barcode.toLowerCase().includes(search) ||
+ product.producer.toLowerCase().includes(search);
+
+ return matchesCategory && matchesSearch;
+ });
+ }, [tableFilters.category, tableFilters.search]);
+ const pages = Math.max(1, Math.ceil(filteredProducts.length / itemsPerPage));
+
+ useEffect(() => {
+ if (tableFilters.page > pages) {
+ tableFilters.setPage(pages);
+ }
+ }, [pages, tableFilters]);
return (
-
+
-
+
@@ -78,14 +91,14 @@ export default function Layout() {