From fb359f5e593c697eeaf15ab988d1963031e8bfa8 Mon Sep 17 00:00:00 2001 From: althafdaa Date: Wed, 24 Jul 2024 22:35:41 +0700 Subject: [PATCH 1/5] feat: create filter for event and rating --- src/components/circle/FilterDrawer.tsx | 57 ++++++++++++++----- .../detail-page/EditGeneralInfoSection.tsx | 4 +- .../circle/useParseClientQueryToParams.ts | 4 +- src/hooks/event/useGetEvent.ts | 23 ++++++-- src/pages/index.tsx | 57 ++++++++++++++++++- src/pages/join.tsx | 4 +- src/types/circle.ts | 31 ++++++++-- 7 files changed, 151 insertions(+), 29 deletions(-) diff --git a/src/components/circle/FilterDrawer.tsx b/src/components/circle/FilterDrawer.tsx index 4808e45..24715d6 100644 --- a/src/components/circle/FilterDrawer.tsx +++ b/src/components/circle/FilterDrawer.tsx @@ -22,7 +22,7 @@ import { useGetWorkType } from '@/hooks/circle/useGetWorkType'; import { prettifyError } from '@/utils/helper'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; -import { CircleFilterWithNoSearch } from '@/types/circle'; +import { CircleFilterWithNoSearch, RATING_ENUM } from '@/types/circle'; import { useParseCircleQueryToParams } from '@/hooks/circle/useParseClientQueryToParams'; const WorkTypeSection = () => { @@ -224,25 +224,54 @@ const MainFilter = () => { (state) => state.setDrawerFilterStep, ); const filterForm = useFormContext(); + const { filter } = useParseCircleQueryToParams(); return ( <> + {!!filter.event && ( + { + return ( + Day} + orientation="horizontal" + isDisabled={disabled} + {...fields} + onValueChange={(a) => onChange(a)} + > + First Day + Second Day + Both Days + + ); + }} + /> + )} + { + name="rating" + render={({ field }) => { return ( - Day} - orientation="horizontal" - isDisabled={disabled} - {...fields} - onValueChange={(a) => onChange(a)} + field.onChange(val)} + label={
Rating
} > - First Day - Second Day - Both Days -
+
+ {RATING_ENUM.map((x) => { + return ( + + {x} + + ); + })} +
+ ); }} /> @@ -318,6 +347,7 @@ const FilterDrawer = () => { day: filter.day, fandom_id: filter.fandom_id, work_type_id: filter.work_type_id, + rating: filter.rating, }); } }, [open]); @@ -343,6 +373,7 @@ const FilterDrawer = () => { day: '', fandom_id: [], work_type_id: [], + rating: [], }, { keepTouched: true, diff --git a/src/components/circle/detail-page/EditGeneralInfoSection.tsx b/src/components/circle/detail-page/EditGeneralInfoSection.tsx index bbd7a30..fe9e16d 100644 --- a/src/components/circle/detail-page/EditGeneralInfoSection.tsx +++ b/src/components/circle/detail-page/EditGeneralInfoSection.tsx @@ -11,7 +11,7 @@ import { uploadService } from '@/services/upload'; import { EditGeneralInfoPayload, editGeneralInfoPayload, - ratingEnum, + RATING_ENUM, updateCirclePayload, } from '@/types/circle'; import { prettifyError } from '@/utils/helper'; @@ -198,7 +198,7 @@ function EditGeneralInfoSection() { errorMessage={formState.errors[field.name]?.message} selectionMode="single" > - {ratingEnum.map((id) => { + {RATING_ENUM.map((id) => { return ( { @@ -21,7 +23,7 @@ export const useParseCircleQueryToParams = () => { } const isActive = Object.entries(params).some(([key, values]) => { - return key !== 'search' && values.length > 0; + return key !== 'search' && key !== 'event' && values.length > 0; }); return { filter: params, diff --git a/src/hooks/event/useGetEvent.ts b/src/hooks/event/useGetEvent.ts index c6d1681..e4806c9 100644 --- a/src/hooks/event/useGetEvent.ts +++ b/src/hooks/event/useGetEvent.ts @@ -1,13 +1,28 @@ import { eventService } from '@/services/event'; -import { useQuery } from '@tanstack/react-query'; +import { UndefinedInitialDataOptions, useQuery } from '@tanstack/react-query'; +type QueryFnData = Awaited>['data']; +type Options = Omit, 'queryKey'>; +type PickedOptions = Partial< + Pick< + Options, + | 'refetchOnMount' + | 'refetchOnReconnect' + | 'refetchOnWindowFocus' + | 'enabled' + | 'staleTime' + > +>; -export const useGetEvents = ( - params: Parameters[0], -) => { +type Params = Parameters[0]; + +export const useGetEvents = (params: Params, options?: PickedOptions) => { return useQuery({ queryKey: ['/v1/event', params], queryFn: async () => (await eventService.getEvents(params)).data, retry: 0, refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + ...options, }); }; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 90b3d27..3f0f9c1 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -5,6 +5,8 @@ import { Popover, PopoverContent, PopoverTrigger, + Radio, + RadioGroup, } from '@nextui-org/react'; import { prettifyError } from '@/utils/helper'; import { useGetCirclesInfinite } from '@/hooks/circle/useGetCirclesInfinite'; @@ -18,6 +20,8 @@ import MegaphoneIcon from '@/icons/MegaphoneIcon'; import { classNames } from '@/utils/classNames'; import TVIcon from '@/icons/TVIcon'; import { useSession } from '@/components/providers/SessionProvider'; +import { useGetEvents } from '@/hooks/event/useGetEvent'; +import { useRouter } from 'next/router'; const FilterDrawer = dynamic(() => import('@/components/circle/FilterDrawer'), { ssr: false, @@ -168,6 +172,55 @@ const JoinAsCircleCTA = () => { ); }; +const EventChipsFilter = () => { + const { data, error } = useGetEvents( + { limit: 2, page: 1 }, + { staleTime: Infinity }, + ); + const router = useRouter(); + if (!data || data.length === 0 || error) return null; + return ( +
+
    + {data.map((ev) => { + const isSelected = router.query.event === ev.slug; + return ( +
  • + { + const copy = { ...router.query }; + if (isSelected) { + delete copy.event; + return copy; + } else { + return { + ...copy, + event: ev.slug, + }; + } + })(), + }} + shallow + > + {ev.name} + +
  • + ); + })} +
+
+ ); +}; + export default function Home() { const setOpen = useDrawerFilterStore((state) => state.setDrawerFilterIsOpen); const { isActive } = useParseCircleQueryToParams(); @@ -179,7 +232,7 @@ export default function Home() {

Discover Circles

-
+
+ + ); diff --git a/src/pages/join.tsx b/src/pages/join.tsx index c0b2861..4ae4024 100644 --- a/src/pages/join.tsx +++ b/src/pages/join.tsx @@ -3,7 +3,7 @@ import Spin from '@/components/general/Spin'; import { useSession } from '@/components/providers/SessionProvider'; import { useOnboarding } from '@/hooks/circle/useOnboarding'; import MegaphoneIcon from '@/icons/MegaphoneIcon'; -import { onboardingPayloadSchema, ratingEnum } from '@/types/circle'; +import { onboardingPayloadSchema, RATING_ENUM } from '@/types/circle'; import { zodResolver } from '@hookform/resolvers/zod'; import { Button, Input, Select, SelectItem } from '@nextui-org/react'; import { useRouter } from 'next/router'; @@ -115,7 +115,7 @@ function JoinPage() {