diff --git a/app/search/[collection]/page.tsx b/app/search/[collection]/page.tsx
index d1a5b242a..547d20180 100644
--- a/app/search/[collection]/page.tsx
+++ b/app/search/[collection]/page.tsx
@@ -1,4 +1,4 @@
-import { getCollection, getCollectionProducts } from 'lib/shopify';
+import { getCollection, getCollectionProducts, getMenu } from 'lib/shopify';
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
@@ -6,7 +6,9 @@ import Breadcrumb from 'components/breadcrumb';
import BreadcrumbHome from 'components/breadcrumb/breadcrumb-home';
import Grid from 'components/grid';
import ProductGridItems from 'components/layout/product-grid-items';
-import Filters from 'components/layout/search/filters';
+import FiltersList from 'components/layout/search/filters/filters-list';
+import MobileFilters from 'components/layout/search/filters/mobile-filters';
+import SubMenu from 'components/layout/search/filters/sub-menu';
import SortingMenu from 'components/layout/search/sorting-menu';
import {
AVAILABILITY_FILTER_ID,
@@ -94,10 +96,14 @@ export default async function CategoryPage({
reverse,
...(filtersInput.length ? { filters: filtersInput } : {})
});
-
const collectionData = getCollection(params.collection);
+ const menuData = getMenu('main-menu');
- const [{ products, filters }, collection] = await Promise.all([productsData, collectionData]);
+ const [{ products, filters }, collection, menu] = await Promise.all([
+ productsData,
+ collectionData,
+ menuData
+ ]);
return (
<>
@@ -107,12 +113,13 @@ export default async function CategoryPage({
{collection ? (
-
+
{collection.title}
{collection.description}
) : null}
-
+
+
@@ -121,7 +128,9 @@ export default async function CategoryPage({
) : (
diff --git a/components/layout/navbar/main-menu.tsx b/components/layout/navbar/main-menu.tsx
index e296bc60a..072a91297 100644
--- a/components/layout/navbar/main-menu.tsx
+++ b/components/layout/navbar/main-menu.tsx
@@ -1,6 +1,6 @@
'use client';
-import { Popover, Transition } from '@headlessui/react';
+import { Popover, PopoverGroup, PopoverPanel, Transition } from '@headlessui/react';
import clsx from 'clsx';
import { Menu } from 'lib/shopify/types';
import Link from 'next/link';
@@ -13,7 +13,7 @@ const MainMenu = ({ menu }: { menu: Menu[] }) => {
return menu.length ? (
-
+
{menu.map((item: Menu) => {
const isActiveItem =
@@ -62,7 +62,7 @@ const MainMenu = ({ menu }: { menu: Menu[] }) => {
leaveTo="opacity-0"
show={isOpen}
>
-
@@ -80,14 +80,14 @@ const MainMenu = ({ menu }: { menu: Menu[] }) => {
))}
-
+
);
})}
-
+
) : null;
};
diff --git a/components/layout/search/filter/dropdown.tsx b/components/layout/search/filter/dropdown.tsx
deleted file mode 100644
index 31daa25ce..000000000
--- a/components/layout/search/filter/dropdown.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-'use client';
-
-import { usePathname, useSearchParams } from 'next/navigation';
-import { useEffect, useRef, useState } from 'react';
-
-import { ChevronDownIcon } from '@heroicons/react/24/outline';
-import type { ListItem } from '.';
-import { FilterItem } from './item';
-
-export default function FilterItemDropdown({ list }: { list: ListItem[] }) {
- const pathname = usePathname();
- const searchParams = useSearchParams();
- const [active, setActive] = useState('');
- const [openSelect, setOpenSelect] = useState(false);
- const ref = useRef
(null);
-
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (ref.current && !ref.current.contains(event.target as Node)) {
- setOpenSelect(false);
- }
- };
-
- window.addEventListener('click', handleClickOutside);
- return () => window.removeEventListener('click', handleClickOutside);
- }, []);
-
- useEffect(() => {
- list.forEach((listItem: ListItem) => {
- if (
- ('path' in listItem && pathname === listItem.path) ||
- ('slug' in listItem && searchParams.get('sort') === listItem.slug)
- ) {
- setActive(listItem.title);
- }
- });
- }, [pathname, list, searchParams]);
-
- return (
-
-
{
- setOpenSelect(!openSelect);
- }}
- className="flex w-full items-center justify-between rounded border border-black/30 px-4 py-2 text-sm dark:border-white/30"
- >
-
{active}
-
-
- {openSelect && (
-
{
- setOpenSelect(false);
- }}
- className="absolute z-40 w-full rounded-b-md bg-white p-4 shadow-md dark:bg-black"
- >
- {list.map((item: ListItem, i) => (
-
- ))}
-
- )}
-
- );
-}
diff --git a/components/layout/search/filter/index.tsx b/components/layout/search/filter/index.tsx
deleted file mode 100644
index e5b102fbf..000000000
--- a/components/layout/search/filter/index.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { SortFilterItem } from 'lib/constants';
-import { Suspense } from 'react';
-import FilterItemDropdown from './dropdown';
-import { FilterItem } from './item';
-
-export type ListItem = SortFilterItem | PathFilterItem;
-export type PathFilterItem = { title: string; path: string };
-
-function FilterItemList({ list }: { list: ListItem[] }) {
- return (
- <>
- {list.map((item: ListItem, i) => (
-
- ))}
- >
- );
-}
-
-export default function FilterList({ list, title }: { list: ListItem[]; title?: string }) {
- return (
- <>
-
- >
- );
-}
diff --git a/components/layout/search/filter/item.tsx b/components/layout/search/filter/item.tsx
deleted file mode 100644
index 3fce8e8a9..000000000
--- a/components/layout/search/filter/item.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-'use client';
-
-import clsx from 'clsx';
-import type { SortFilterItem } from 'lib/constants';
-import { createUrl } from 'lib/utils';
-import Link from 'next/link';
-import { usePathname, useSearchParams } from 'next/navigation';
-import type { ListItem, PathFilterItem } from '.';
-
-function PathFilterItem({ item }: { item: PathFilterItem }) {
- const pathname = usePathname();
- const searchParams = useSearchParams();
- const active = pathname === item.path;
- const newParams = new URLSearchParams(searchParams.toString());
- const DynamicTag = active ? 'p' : Link;
-
- newParams.delete('q');
-
- return (
-
-
- {item.title}
-
-
- );
-}
-
-function SortFilterItem({ item }: { item: SortFilterItem }) {
- const pathname = usePathname();
- const searchParams = useSearchParams();
- const active = searchParams.get('sort') === item.slug;
- const q = searchParams.get('q');
- const href = createUrl(
- pathname,
- new URLSearchParams({
- ...(q && { q }),
- ...(item.slug && item.slug.length && { sort: item.slug })
- })
- );
- const DynamicTag = active ? 'p' : Link;
-
- return (
-
-
- {item.title}
-
-
- );
-}
-
-export function FilterItem({ item }: { item: ListItem }) {
- return 'path' in item ? : ;
-}
diff --git a/components/layout/search/filters/filters-list.tsx b/components/layout/search/filters/filters-list.tsx
index 84714cb0a..79202ff56 100644
--- a/components/layout/search/filters/filters-list.tsx
+++ b/components/layout/search/filters/filters-list.tsx
@@ -1,10 +1,12 @@
'use client';
+import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/react';
+import { ChevronDownIcon } from '@heroicons/react/24/outline';
import clsx from 'clsx';
import { Filter } from 'lib/shopify/types';
import { createUrl } from 'lib/utils';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
-const Filters = ({ filters }: { filters: Filter[] }) => {
+const Filters = ({ filters, defaultOpen = true }: { filters: Filter[]; defaultOpen?: boolean }) => {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
@@ -31,9 +33,17 @@ const Filters = ({ filters }: { filters: Filter[] }) => {
return (
);
diff --git a/components/layout/search/filters/index.tsx b/components/layout/search/filters/index.tsx
deleted file mode 100644
index 033c7f450..000000000
--- a/components/layout/search/filters/index.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { getMenu } from 'lib/shopify';
-import { Filter } from 'lib/shopify/types';
-import Link from 'next/link';
-import FiltersList from './filters-list';
-
-const Filters = async ({ collection, filters }: { collection: string; filters: Filter[] }) => {
- const menu = await getMenu('main-menu');
- const subMenu = menu.find((item) => item.path === `/search/${collection}`)?.items || [];
- return (
-
- {subMenu.length ? (
- <>
-
Categories
-
- {subMenu.map((subMenuItem) => (
- -
-
- {subMenuItem.title}
-
-
- ))}
-
- >
- ) : null}
-
Filters
-
-
- );
-};
-
-export default Filters;
diff --git a/components/layout/search/filters/mobile-filters.tsx b/components/layout/search/filters/mobile-filters.tsx
new file mode 100644
index 000000000..1e3a25418
--- /dev/null
+++ b/components/layout/search/filters/mobile-filters.tsx
@@ -0,0 +1,79 @@
+'use client';
+
+import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react';
+import { FunnelIcon } from '@heroicons/react/24/outline';
+import { XMarkIcon } from '@heroicons/react/24/solid';
+import { Filter, Menu } from 'lib/shopify/types';
+import { Fragment, useState } from 'react';
+import Filters from './filters-list';
+import SubMenu from './sub-menu';
+
+const MobileFilters = ({
+ collection,
+ filters,
+ menu
+}: {
+ collection: string;
+ filters: Filter[];
+ menu: Menu[];
+}) => {
+ const [openDialog, setOpenDialog] = useState(false);
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default MobileFilters;
diff --git a/components/layout/search/filters/sub-menu.tsx b/components/layout/search/filters/sub-menu.tsx
new file mode 100644
index 000000000..a94ea8d68
--- /dev/null
+++ b/components/layout/search/filters/sub-menu.tsx
@@ -0,0 +1,26 @@
+import { Menu } from 'lib/shopify/types';
+import Link from 'next/link';
+
+const SubMenu = ({ menu, collection }: { menu: Menu[]; collection: string }) => {
+ const subMenu = menu.find((item) => item.path === `/search/${collection}`)?.items || [];
+
+ return subMenu.length ? (
+ <>
+ Categories
+
+ {subMenu.map((subMenuItem) => (
+ -
+
+ {subMenuItem.title}
+
+
+ ))}
+
+ >
+ ) : null;
+};
+
+export default SubMenu;
diff --git a/components/layout/search/sorting-menu/index.tsx b/components/layout/search/sorting-menu/index.tsx
index 5296800b0..b3bdc0420 100644
--- a/components/layout/search/sorting-menu/index.tsx
+++ b/components/layout/search/sorting-menu/index.tsx
@@ -1,6 +1,6 @@
'use client';
-import { Menu, Transition } from '@headlessui/react';
+import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react';
import { ChevronDownIcon } from '@heroicons/react/20/solid';
import { defaultSort, sorting } from 'lib/constants';
import { useSearchParams } from 'next/navigation';
@@ -14,7 +14,7 @@ const SortingMenu = () => {
return (