cal/packages/features/troubleshooter/store.ts
sean-brydon bdd3b132d4
feat: troubleshooter with weekly view (V2) (#12280)
* Inital UI + layout setup

* use booker approach of grid

* event-select - sidebar + store work

* adds get schedule by event-type-slug

* Calendar toggle

* Load schedule from event slug

* Add busy events to calendar

* useschedule

* Store more event info than just slug

* Add date override to calendar

* Changes sizes on smaller screens

* add event title as a tooltip

* Ensure header navigation works

* Stop navigator throwing errors on inital render

* Correct br

* Event duration fixes

* Add getMoreInfo if user is authed with current request.username

* Add calendar color map wip

* Add WIP comments for coloured outlines

* Revert more info changes

* Calculate date override correctly

* Add description option

* Fix inital schedule data not being populated

* Nudge overlap over to make it clearer

* Fix disabled state

* WIP on math logic

* Event list overlapping events logic

* NIT about width

* i18n + manage calendars link

* Delete old troubleshooter

* Update packages/features/calendars/weeklyview/components/event/EventList.tsx

* Remove t-slots

* Fix i18n & install calendar action

* sm:imrovments

* NITS

* Fix types

* fix: back button

* Month prop null as we control from query param

* Add head SEO

* Fix headseo import

* Fix date override tests
2023-11-20 17:49:33 +05:30

111 lines
3.5 KiB
TypeScript

import { useEffect } from "react";
import { create } from "zustand";
import dayjs from "@calcom/dayjs";
import { updateQueryParam, getQueryParam, removeQueryParam } from "../bookings/Booker/utils/query-param";
/**
* Arguments passed into store initializer, containing
* the event data.
*/
type StoreInitializeType = {
month: string | null;
};
type EventType = {
id: number;
slug: string;
duration: number;
};
export type TroubleshooterStore = {
event: EventType | null;
setEvent: (eventSlug: EventType) => void;
month: string | null;
setMonth: (month: string | null) => void;
selectedDate: string | null;
setSelectedDate: (date: string | null) => void;
addToSelectedDate: (days: number) => void;
initialize: (data: StoreInitializeType) => void;
calendarToColorMap: Record<string, string>;
addToCalendarToColorMap: (calendarId: string | undefined, color: string) => void;
};
/**
* The booker store contains the data of the component's
* current state. This data can be reused within child components
* by importing this hook.
*
* See comments in interface above for more information on it's specific values.
*/
export const useTroubleshooterStore = create<TroubleshooterStore>((set, get) => ({
selectedDate: getQueryParam("date") || null,
setSelectedDate: (selectedDate: string | null) => {
// unset selected date
if (!selectedDate) {
removeQueryParam("date");
return;
}
const currentSelection = dayjs(get().selectedDate);
const newSelection = dayjs(selectedDate);
set({ selectedDate });
updateQueryParam("date", selectedDate ?? "");
// Setting month make sure small calendar in fullscreen layouts also updates.
if (newSelection.month() !== currentSelection.month()) {
set({ month: newSelection.format("YYYY-MM") });
updateQueryParam("month", newSelection.format("YYYY-MM"));
}
},
addToSelectedDate: (days: number) => {
const selectedDate = get().selectedDate;
const currentSelection = selectedDate ? dayjs(get().selectedDate) : dayjs();
const newSelection = currentSelection.add(days, "day");
const newSelectionFormatted = newSelection.format("YYYY-MM-DD");
if (newSelection.month() !== currentSelection.month()) {
set({ month: newSelection.format("YYYY-MM") });
updateQueryParam("month", newSelection.format("YYYY-MM"));
}
set({ selectedDate: newSelectionFormatted });
updateQueryParam("date", newSelectionFormatted);
},
event: null,
setEvent: (event: EventType) => {
set({ event });
updateQueryParam("eventType", event.slug ?? "");
},
month: getQueryParam("month") || getQueryParam("date") || dayjs().format("YYYY-MM"),
setMonth: (month: string | null) => {
set({ month });
updateQueryParam("month", month ?? "");
get().setSelectedDate(null);
},
initialize: ({ month }: StoreInitializeType) => {
if (month) {
set({ month });
updateQueryParam("month", month);
}
//removeQueryParam("layout");
},
calendarToColorMap: {},
addToCalendarToColorMap: (calendarId: string | undefined, color: string) => {
if (!calendarId) return;
const calendarToColorMap = get().calendarToColorMap;
calendarToColorMap[calendarId] = color;
set({ calendarToColorMap });
},
}));
export const useInitalizeTroubleshooterStore = ({ month }: StoreInitializeType) => {
const initializeStore = useTroubleshooterStore((state) => state.initialize);
useEffect(() => {
initializeStore({
month,
});
}, [initializeStore, month]);
};