mirror of
https://github.com/vercel/commerce.git
synced 2025-05-09 19:27:53 +00:00
rm some more
This commit is contained in:
parent
38e9056509
commit
b022efc666
@ -1,37 +0,0 @@
|
|||||||
import clsx from 'clsx';
|
|
||||||
import { Suspense } from 'react';
|
|
||||||
|
|
||||||
import { getCollections } from 'lib/shopify';
|
|
||||||
import FilterList from './filter';
|
|
||||||
|
|
||||||
async function CollectionList() {
|
|
||||||
const collections = await getCollections();
|
|
||||||
return <FilterList list={collections} title="Collections" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const skeleton = 'mb-3 h-4 w-5/6 animate-pulse rounded';
|
|
||||||
const activeAndTitles = 'bg-neutral-800 dark:bg-neutral-300';
|
|
||||||
const items = 'bg-neutral-400 dark:bg-neutral-700';
|
|
||||||
|
|
||||||
export default function Collections() {
|
|
||||||
return (
|
|
||||||
<Suspense
|
|
||||||
fallback={
|
|
||||||
<div className="col-span-2 hidden h-[400px] w-full flex-none py-4 lg:block">
|
|
||||||
<div className={clsx(skeleton, activeAndTitles)} />
|
|
||||||
<div className={clsx(skeleton, activeAndTitles)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
<div className={clsx(skeleton, items)} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<CollectionList />
|
|
||||||
</Suspense>
|
|
||||||
);
|
|
||||||
}
|
|
@ -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<HTMLDivElement>(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 (
|
|
||||||
<div className="relative" ref={ref}>
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
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"
|
|
||||||
>
|
|
||||||
<div>{active}</div>
|
|
||||||
<ChevronDownIcon className="h-4" />
|
|
||||||
</div>
|
|
||||||
{openSelect && (
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
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) => (
|
|
||||||
<FilterItem key={i} item={item} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -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) => (
|
|
||||||
<FilterItem key={i} item={item} />
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function FilterList({ list, title }: { list: ListItem[]; title?: string }) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<nav>
|
|
||||||
{title ? (
|
|
||||||
<h3 className="hidden text-xs text-neutral-500 md:block dark:text-neutral-400">
|
|
||||||
{title}
|
|
||||||
</h3>
|
|
||||||
) : null}
|
|
||||||
<ul className="hidden md:block">
|
|
||||||
<Suspense fallback={null}>
|
|
||||||
<FilterItemList list={list} />
|
|
||||||
</Suspense>
|
|
||||||
</ul>
|
|
||||||
<ul className="md:hidden">
|
|
||||||
<Suspense fallback={null}>
|
|
||||||
<FilterItemDropdown list={list} />
|
|
||||||
</Suspense>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -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 (
|
|
||||||
<li className="mt-2 flex text-black dark:text-white" key={item.title}>
|
|
||||||
<DynamicTag
|
|
||||||
href={createUrl(item.path, newParams)}
|
|
||||||
className={clsx(
|
|
||||||
'w-full text-sm underline-offset-4 hover:underline dark:hover:text-neutral-100',
|
|
||||||
{
|
|
||||||
'underline underline-offset-4': active
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{item.title}
|
|
||||||
</DynamicTag>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (
|
|
||||||
<li className="mt-2 flex text-sm text-black dark:text-white" key={item.title}>
|
|
||||||
<DynamicTag
|
|
||||||
prefetch={!active ? false : undefined}
|
|
||||||
href={href}
|
|
||||||
className={clsx('w-full hover:underline hover:underline-offset-4', {
|
|
||||||
'underline underline-offset-4': active
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{item.title}
|
|
||||||
</DynamicTag>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function FilterItem({ item }: { item: ListItem }) {
|
|
||||||
return 'path' in item ? <PathFilterItem item={item} /> : <SortFilterItem item={item} />;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user