4
0
forked from crowetic/commerce

Fixes search page bugs. (#1019)

This commit is contained in:
Michael Novotny 2023-05-12 16:02:51 -07:00 committed by GitHub
parent a0c0d10fae
commit f5dade74fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 13 deletions

View File

@ -4,6 +4,7 @@ import { notFound } from 'next/navigation';
import Grid from 'components/grid'; import Grid from 'components/grid';
import ProductGridItems from 'components/layout/product-grid-items'; import ProductGridItems from 'components/layout/product-grid-items';
import { defaultSort, sorting } from 'lib/constants';
export const runtime = 'edge'; export const runtime = 'edge';
@ -32,8 +33,16 @@ export async function generateMetadata({
}; };
} }
export default async function CategoryPage({ params }: { params: { collection: string } }) { export default async function CategoryPage({
const products = await getCollectionProducts(params.collection); params,
searchParams
}: {
params: { collection: string };
searchParams?: { [key: string]: string | string[] | undefined };
}) {
const { sort } = searchParams as { [key: string]: string };
const { sortKey, reverse } = sorting.find((item) => item.slug === sort) || defaultSort;
const products = await getCollectionProducts({ collection: params.collection, sortKey, reverse });
return ( return (
<section> <section>

View File

@ -4,7 +4,7 @@ import Link from 'next/link';
export async function Carousel() { export async function Carousel() {
// Collections that start with `hidden-*` are hidden from the search page. // Collections that start with `hidden-*` are hidden from the search page.
const products = await getCollectionProducts('hidden-homepage-carousel'); const products = await getCollectionProducts({ collection: 'hidden-homepage-carousel' });
if (!products?.length) return null; if (!products?.length) return null;

View File

@ -37,7 +37,9 @@ function ThreeItemGridItem({
export async function ThreeItemGrid() { export async function ThreeItemGrid() {
// Collections that start with `hidden-*` are hidden from the search page. // Collections that start with `hidden-*` are hidden from the search page.
const homepageItems = await getCollectionProducts('hidden-homepage-featured-items'); const homepageItems = await getCollectionProducts({
collection: 'hidden-homepage-featured-items'
});
if (!homepageItems[0] || !homepageItems[1] || !homepageItems[2]) return null; if (!homepageItems[0] || !homepageItems[1] || !homepageItems[2]) return null;

View File

@ -3,6 +3,7 @@
import { useRouter, useSearchParams } from 'next/navigation'; import { useRouter, useSearchParams } from 'next/navigation';
import SearchIcon from 'components/icons/search'; import SearchIcon from 'components/icons/search';
import { createUrl } from 'lib/utils';
export default function Search() { export default function Search() {
const router = useRouter(); const router = useRouter();
@ -13,12 +14,15 @@ export default function Search() {
const val = e.target as HTMLFormElement; const val = e.target as HTMLFormElement;
const search = val.search as HTMLInputElement; const search = val.search as HTMLInputElement;
const newParams = new URLSearchParams(searchParams.toString());
if (search.value) { if (search.value) {
router.push(`/search?q=${search.value}`); newParams.set('q', search.value);
} else { } else {
router.push(`/search`); newParams.delete('q');
} }
router.push(createUrl('/search', newParams));
} }
return ( return (

View File

@ -12,6 +12,9 @@ function PathFilterItem({ item }: { item: PathFilterItem }) {
const pathname = usePathname(); const pathname = usePathname();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const [active, setActive] = useState(pathname === item.path); const [active, setActive] = useState(pathname === item.path);
const newParams = new URLSearchParams(searchParams.toString());
newParams.delete('q');
useEffect(() => { useEffect(() => {
setActive(pathname === item.path); setActive(pathname === item.path);
@ -20,7 +23,7 @@ function PathFilterItem({ item }: { item: PathFilterItem }) {
return ( return (
<li className="mt-2 flex text-sm text-gray-400" key={item.title}> <li className="mt-2 flex text-sm text-gray-400" key={item.title}>
<Link <Link
href={createUrl(item.path, searchParams)} href={createUrl(item.path, newParams)}
className={clsx('w-full hover:text-gray-800 dark:hover:text-gray-100', { className={clsx('w-full hover:text-gray-800 dark:hover:text-gray-100', {
'text-gray-600 dark:text-gray-400': !active, 'text-gray-600 dark:text-gray-400': !active,
'font-semibold text-black dark:text-white': active 'font-semibold text-black dark:text-white': active
@ -36,6 +39,7 @@ function SortFilterItem({ item }: { item: SortFilterItem }) {
const pathname = usePathname(); const pathname = usePathname();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const [active, setActive] = useState(searchParams.get('sort') === item.slug); const [active, setActive] = useState(searchParams.get('sort') === item.slug);
const q = searchParams.get('q');
useEffect(() => { useEffect(() => {
setActive(searchParams.get('sort') === item.slug); setActive(searchParams.get('sort') === item.slug);
@ -43,7 +47,13 @@ function SortFilterItem({ item }: { item: SortFilterItem }) {
const href = const href =
item.slug && item.slug.length item.slug && item.slug.length
? createUrl(pathname, new URLSearchParams({ sort: item.slug })) ? createUrl(
pathname,
new URLSearchParams({
...(q && { q }),
sort: item.slug
})
)
: pathname; : pathname;
return ( return (

View File

@ -257,16 +257,26 @@ export async function getCollection(handle: string): Promise<Collection | undefi
return reshapeCollection(res.body.data.collection); return reshapeCollection(res.body.data.collection);
} }
export async function getCollectionProducts(handle: string): Promise<Product[]> { export async function getCollectionProducts({
collection,
reverse,
sortKey
}: {
collection: string;
reverse?: boolean;
sortKey?: string;
}): Promise<Product[]> {
const res = await shopifyFetch<ShopifyCollectionProductsOperation>({ const res = await shopifyFetch<ShopifyCollectionProductsOperation>({
query: getCollectionProductsQuery, query: getCollectionProductsQuery,
variables: { variables: {
handle handle: collection,
reverse,
sortKey
} }
}); });
if (!res.body.data.collection) { if (!res.body.data.collection) {
console.log('No collection found for handle', handle); console.log(`No collection found for \`${collection}\``);
return []; return [];
} }

View File

@ -37,9 +37,13 @@ export const getCollectionsQuery = /* GraphQL */ `
`; `;
export const getCollectionProductsQuery = /* GraphQL */ ` export const getCollectionProductsQuery = /* GraphQL */ `
query getCollectionProducts($handle: String!) { query getCollectionProducts(
$handle: String!
$sortKey: ProductCollectionSortKeys
$reverse: Boolean
) {
collection(handle: $handle) { collection(handle: $handle) {
products(first: 100) { products(sortKey: $sortKey, reverse: $reverse, first: 100) {
edges { edges {
node { node {
...product ...product

View File

@ -201,6 +201,8 @@ export type ShopifyCollectionProductsOperation = {
}; };
variables: { variables: {
handle: string; handle: string;
reverse?: boolean;
sortKey?: string;
}; };
}; };