From a077bbe7539db7f2c51e97b6cc38bdd7eab5ec02 Mon Sep 17 00:00:00 2001 From: Chloe Date: Fri, 5 Jul 2024 10:59:50 +0700 Subject: [PATCH] fix: improve MMY filters Signed-off-by: Chloe --- components/filters/actions.ts | 12 +++++++ components/filters/field.tsx | 11 ++++-- components/filters/filters-list.tsx | 49 ++++++++++++++++++++++---- components/filters/hompage-filters.tsx | 15 ++------ components/filters/index.tsx | 8 ++--- components/spinner.tsx | 27 ++++++++++++++ lib/shopify/index.ts | 8 +++-- lib/shopify/queries/metaobject.ts | 15 ++++++++ 8 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 components/filters/actions.ts create mode 100644 components/spinner.tsx diff --git a/components/filters/actions.ts b/components/filters/actions.ts new file mode 100644 index 000000000..55c4001dc --- /dev/null +++ b/components/filters/actions.ts @@ -0,0 +1,12 @@ +'use server'; + +import { getAllMetaobjects } from 'lib/shopify'; + +export const fetMetaobjects = async (type: string) => { + try { + const data = await getAllMetaobjects(type); + return data; + } catch (error) { + console.log('fetMetaobjects action', error); + } +}; diff --git a/components/filters/field.tsx b/components/filters/field.tsx index bb105b0f0..77819c315 100644 --- a/components/filters/field.tsx +++ b/components/filters/field.tsx @@ -8,6 +8,7 @@ import { ComboboxOptions } from '@headlessui/react'; import { ChevronDownIcon } from '@heroicons/react/16/solid'; +import Spinner from 'components/spinner'; import get from 'lodash.get'; import { useCallback, useState } from 'react'; @@ -22,6 +23,7 @@ type FilterFieldProps = { getId: (option: T) => string; disabled?: boolean; autoFocus?: boolean; + isLoading?: boolean; }; const FilterField = ({ @@ -32,6 +34,7 @@ const FilterField = ({ displayKey = 'name', getId, disabled, + isLoading, autoFocus = false }: FilterFieldProps) => { const [query, setQuery] = useState(''); @@ -63,7 +66,7 @@ const FilterField = ({ onChange={onChange} onClose={() => setQuery('')} immediate - disabled={disabled} + disabled={disabled || isLoading} >
({ autoFocus={autoFocus} /> - + {isLoading ? ( + + ) : ( + + )}
{ +const FiltersList = ({ makes, menu, autoFocusField }: FiltersListProps) => { const params = useParams<{ collection?: string }>(); const router = useRouter(); const searchParams = useSearchParams(); @@ -32,6 +31,12 @@ const FiltersList = ({ years, makes, models, menu, autoFocusField }: FiltersList ); const makeIdFromSearchParams = searchParams.get(MAKE_FILTER_ID); + const modelIdFromSearchParams = searchParams.get(MODEL_FILTER_ID); + const yearIdFromSearchParams = searchParams.get(YEAR_FILTER_ID); + + const [models, setModels] = useState([]); + const [years, setYears] = useState([]); + const [isLoading, startTransition] = useTransition(); const [make, setMake] = useState( (partType && @@ -75,13 +80,43 @@ const FiltersList = ({ years, makes, models, menu, autoFocusField }: FiltersList } }, [makeIdFromSearchParams, makes, params.collection, partType]); - const onChangeMake = (value: Metaobject | null) => { + useEffect(() => { + if (make?.id && models.length === 0) { + startTransition(async () => { + const modelsResponse = await fetMetaobjects('make_model_composite'); + if (modelIdFromSearchParams) { + setModel( + (currentModel) => + modelsResponse?.find((model) => model.id === modelIdFromSearchParams) || currentModel + ); + } + setModels(modelsResponse || []); + }); + } + }, [make?.id, modelIdFromSearchParams, models.length]); + + useEffect(() => { + if (model?.id && years.length === 0) { + startTransition(async () => { + const yearsResponse = await fetMetaobjects('make_model_year_composite'); + if (yearIdFromSearchParams) { + setYear( + (currentYear) => + yearsResponse?.find((year) => year.id === yearIdFromSearchParams) || currentYear + ); + } + setYears(yearsResponse || []); + }); + } + }, [model?.id, yearIdFromSearchParams, years.length]); + + const onChangeMake = async (value: Metaobject | null) => { setMake(value); setModel(null); setYear(null); }; - const onChangeModel = (value: Metaobject | null) => { + const onChangeModel = async (value: Metaobject | null) => { setModel(value); setYear(null); }; @@ -134,6 +169,7 @@ const FiltersList = ({ years, makes, models, menu, autoFocusField }: FiltersList getId={(option) => option.id} disabled={!make} autoFocus={autoFocusField === 'model'} + isLoading={isLoading} /> option.id} disabled={!model || !make} autoFocus={autoFocusField === 'year'} + isLoading={isLoading} />