diff --git a/apps/web/pages/bookings/[status].tsx b/apps/web/pages/bookings/[status].tsx
index ab7a348568..2277a195cd 100644
--- a/apps/web/pages/bookings/[status].tsx
+++ b/apps/web/pages/bookings/[status].tsx
@@ -5,7 +5,7 @@ import { Fragment } from "react";
import { z } from "zod";
import { WipeMyCalActionButton } from "@calcom/app-store/wipemycalother/components";
-import BookingLayout, { useFilterStore } from "@calcom/features/bookings/layout/BookingLayout";
+import BookingLayout from "@calcom/features/bookings/layout/BookingLayout";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { RouterInputs, RouterOutputs, trpc } from "@calcom/trpc/react";
import { Alert, Button, EmptyScreen, Icon } from "@calcom/ui";
@@ -42,7 +42,6 @@ const querySchema = z.object({
});
export default function Bookings() {
- // const selectedUsers = useFilterStore((state) => state.selectedUsers);
const router = useRouter();
const { status } = router.isReady ? querySchema.parse(router.query) : { status: "upcoming" as const };
const { t } = useLocale();
diff --git a/packages/features/bookings/components/TeamsMemberFilter.tsx b/packages/features/bookings/components/TeamsMemberFilter.tsx
index 520b80107e..3fff594622 100644
--- a/packages/features/bookings/components/TeamsMemberFilter.tsx
+++ b/packages/features/bookings/components/TeamsMemberFilter.tsx
@@ -1,27 +1,15 @@
import { Fragment } from "react";
-import shallow from "zustand/shallow";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { RouterOutputs, trpc } from "@calcom/trpc/react";
+import { trpc } from "@calcom/trpc/react";
import { AnimatedPopover, Avatar } from "@calcom/ui";
-import { useFilterStore } from "../layout/BookingLayout";
-
-export type ITeamMemberFilters = RouterOutputs["viewer"]["teams"]["listTeamsandMembers"];
-export type ITeamMemberFilter = ITeamMemberFilters[0];
+import { useFilterQuery } from "../lib/useFilterQuery";
export const TeamsMemberFilter = () => {
- const { selectedUsers, pushSelectedUser, removeSelectedUser } = useFilterStore(
- (state) => ({
- selectedUsers: state.selectedUsers,
- pushSelectedUser: state.pushSelectedUser,
- removeSelectedUser: state.removeSelectedUser,
- }),
- shallow
- );
const { t } = useLocale();
+ const { data: query, pop, push } = useFilterQuery();
const { data } = trpc.viewer.teams.listTeamsandMembers.useQuery();
- // Will be handled up the tree to redirect
if (data?.length === 0) return null;
@@ -48,17 +36,15 @@ export const TeamsMemberFilter = () => {
selected.id === team.id && selected.user.id === member.user.id
- ).length > 0
- }
name={`${member.team.id}-${member.user.id}`}
+ checked={query.userIds?.includes(member.user.id) && query.teamIds?.includes(team.id)}
onChange={(e) => {
if (e.target.checked) {
- pushSelectedUser({ id: team.id, teamName: team.name, user: member.user });
+ push("userIds", member.user.id);
+ push("teamIds", team.id);
} else if (!e.target.checked) {
- removeSelectedUser(member.user.id);
+ pop("userIds", member.user.id);
+ pop("teamIds", team.id);
}
}}
className="text-primary-600 focus:ring-primary-500 inline-flex h-4 w-4 place-self-center justify-self-end rounded border-gray-300 "
diff --git a/packages/features/bookings/layout/BookingLayout.tsx b/packages/features/bookings/layout/BookingLayout.tsx
index 7654e00941..b1c415e037 100644
--- a/packages/features/bookings/layout/BookingLayout.tsx
+++ b/packages/features/bookings/layout/BookingLayout.tsx
@@ -1,11 +1,10 @@
import React, { ComponentProps } from "react";
-import create from "zustand";
import { HorizontalTabs, Shell } from "@calcom/ui";
import { VerticalTabItemProps, HorizontalTabItemProps } from "@calcom/ui/v2";
-import { EventTypeFilter, IEventTypeFilter } from "../components/EventTypeFilter";
-import { TeamsMemberFilter, ITeamMemberFilter } from "../components/TeamsMemberFilter";
+import { EventTypeFilter} from "../components/EventTypeFilter";
+import { TeamsMemberFilter } from "../components/TeamsMemberFilter";
const tabs: (VerticalTabItemProps | HorizontalTabItemProps)[] = [
{
@@ -30,51 +29,6 @@ const tabs: (VerticalTabItemProps | HorizontalTabItemProps)[] = [
},
];
-interface BookingLayoutStoreState {
- selectedEventTypes: IEventTypeFilter[];
- selectedUsers: {
- id: number;
- teamName: string;
- user: ITeamMemberFilter["members"][0]["user"];
- }[];
-}
-interface BookingLayoutStoreActions {
- setSelectedEventTypes: (eventTypes: IEventTypeFilter[]) => void;
- setSelectedUsers: (users: BookingLayoutStoreState["selectedUsers"]) => void;
- pushSelectedEventType: (eventType: IEventTypeFilter) => void;
- pushSelectedUser: (user: BookingLayoutStoreState["selectedUsers"][0]) => void;
- removeSelectedEventType: (eventType: IEventTypeFilter) => void;
- removeSelectedUser: (userId: number) => void;
- clearState: () => void;
-}
-
-// Since this is a layout i thought i'd be best to implement some "Global" component state
-export const useFilterStore = create((set) => ({
- selectedEventTypes: [],
- selectedUsers: [],
- setSelectedEventTypes: (eventTypes) => set({ selectedEventTypes: eventTypes }),
- setSelectedUsers: (users) => set({ selectedUsers: users }),
- pushSelectedEventType: (eventType) => {
- set((state) => ({ selectedEventTypes: [...state.selectedEventTypes, eventType] }));
- },
- pushSelectedUser: (user) => {
- set((state) => ({ selectedUsers: [...state.selectedUsers, user] }));
- },
- removeSelectedEventType: (eventType) => {
- set((state) => ({
- selectedEventTypes: state.selectedEventTypes.filter((type) => type.id !== eventType.id),
- }));
- },
- removeSelectedUser: (userId) => {
- set((state) => {
- return {
- selectedUsers: state.selectedUsers.filter((selected) => selected.user.id !== userId),
- };
- });
- },
- clearState: () => set({ selectedEventTypes: [], selectedUsers: [] }),
-}));
-
export default function BookingLayout({
children,
...rest
@@ -85,8 +39,8 @@ export default function BookingLayout({
{children}
diff --git a/packages/features/bookings/lib/useFilterQuery.tsx b/packages/features/bookings/lib/useFilterQuery.tsx
new file mode 100644
index 0000000000..04429f3ede
--- /dev/null
+++ b/packages/features/bookings/lib/useFilterQuery.tsx
@@ -0,0 +1,56 @@
+import { useRouter } from "next/router";
+import z from "zod";
+
+// Take string and return number
+export const queryNumberSchema = z.preprocess(
+ (a) => parseInt(z.string().parse(a), 10),
+ z.number().positive().array()
+);
+// Take array as a string and return zod array
+export const queryNumberArray = z.preprocess(
+ (a) =>
+ z
+ .string()
+ .parse(a)
+ .split(",")
+ .map((a) => parseInt(a, 10)),
+ z.number().positive().array()
+);
+// Take string and return return zod string array - comma separated
+export const queryStringArray = z.preprocess((a) => z.string().parse(a).split(","), z.string().array());
+
+const filterQuerySchema = z.object({
+ teamIds: queryNumberArray.optional(),
+ status: queryStringArray.optional(), // Not used right now but could be implemented when/if we move status to a filter
+ userIds: queryNumberArray.optional(),
+ eventTypeIds: queryNumberArray.optional(),
+});
+
+type FilterQuerySchema = z.infer;
+type Keys = keyof FilterQuerySchema;
+
+export function useFilterQuery() {
+ const router = useRouter();
+ const data = filterQuerySchema.parse(router.query);
+
+ // push item to key of filterQuerySchema and set new query params in url
+
+ const push = (key: Required, item: string | number) => {
+ const newData = { ...data };
+ const keyData = newData[key] ?? [];
+ // @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ newData[key] = [...keyData, item];
+ router.push({ query: newData });
+ };
+
+ const pop = (key: Required, item: string | number) => {
+ const newData = { ...data };
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore idk how to fix this ?
+ newData[key] = newData[key].filter((a) => a !== item);
+ router.push({ query: newData });
+ };
+
+ return { data, push, pop };
+}
diff --git a/packages/features/package.json b/packages/features/package.json
index c0e2152ca0..0d220f2ce4 100644
--- a/packages/features/package.json
+++ b/packages/features/package.json
@@ -7,7 +7,6 @@
"main": "index.ts",
"dependencies": {
"@lexical/react": "^0.5.0",
- "lexical": "^0.5.0",
- "zustand": "^4.1.5"
+ "lexical": "^0.5.0"
}
}