Removes unused files (#3208)
* Adds next-unused * Cleanup * Update next-unused * Removes next-unused Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
1 parent
93e2246b18
commit
669199e273
10 files changed
-545
No files matched your search
@@ -1,262 +0,0 @@
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid";
|
||||
import { PeriodType } from "@prisma/client";
|
||||
import { memoize } from "lodash";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import dayjs, { Dayjs } from "@calcom/dayjs";
|
||||
import { useEmbedStyles } from "@calcom/embed-core/embed-iframe";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
|
||||
import classNames from "@lib/classNames";
|
||||
import { timeZone } from "@lib/clock";
|
||||
import { weekdayNames } from "@lib/core/i18n/weekday";
|
||||
import { doWorkAsync } from "@lib/doWorkAsync";
|
||||
import isOutOfBounds from "@lib/isOutOfBounds";
|
||||
import getSlots from "@lib/slots";
|
||||
import { WorkingHours } from "@lib/types/schedule";
|
||||
|
||||
import Loader from "@components/Loader";
|
||||
|
||||
type DatePickerProps = {
|
||||
weekStart: string;
|
||||
onDatePicked: (pickedDate: Dayjs) => void;
|
||||
workingHours: WorkingHours[];
|
||||
eventLength: number;
|
||||
date: Dayjs | null;
|
||||
periodType: PeriodType;
|
||||
periodStartDate: Date | null;
|
||||
periodEndDate: Date | null;
|
||||
periodDays: number | null;
|
||||
periodCountCalendarDays: boolean | null;
|
||||
minimumBookingNotice: number;
|
||||
};
|
||||
|
||||
function DatePicker({
|
||||
weekStart,
|
||||
onDatePicked,
|
||||
workingHours,
|
||||
eventLength,
|
||||
date,
|
||||
periodType = PeriodType.UNLIMITED,
|
||||
periodStartDate,
|
||||
periodEndDate,
|
||||
periodDays,
|
||||
periodCountCalendarDays,
|
||||
minimumBookingNotice,
|
||||
}: DatePickerProps): JSX.Element {
|
||||
const { i18n } = useLocale();
|
||||
const [browsingDate, setBrowsingDate] = useState<Dayjs | null>(date);
|
||||
const enabledDateButtonEmbedStyles = useEmbedStyles("enabledDateButton");
|
||||
const disabledDateButtonEmbedStyles = useEmbedStyles("disabledDateButton");
|
||||
const [month, setMonth] = useState<string>("");
|
||||
const [year, setYear] = useState<string>("");
|
||||
const [isFirstMonth, setIsFirstMonth] = useState<boolean>(false);
|
||||
const [daysFromState, setDays] = useState<
|
||||
| {
|
||||
disabled: boolean;
|
||||
date: number;
|
||||
}[]
|
||||
| null
|
||||
>(null);
|
||||
useEffect(() => {
|
||||
if (!browsingDate || (date && browsingDate.utcOffset() !== date?.utcOffset())) {
|
||||
setBrowsingDate(date || dayjs().tz(timeZone()));
|
||||
}
|
||||
}, [date, browsingDate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (browsingDate) {
|
||||
setMonth(browsingDate.toDate().toLocaleString(i18n.language, { month: "long" }));
|
||||
setYear(browsingDate.format("YYYY"));
|
||||
setIsFirstMonth(browsingDate.startOf("month").isBefore(dayjs()));
|
||||
setDays(null);
|
||||
}
|
||||
}, [browsingDate, i18n.language]);
|
||||
|
||||
const isDisabled = (
|
||||
day: number,
|
||||
{
|
||||
browsingDate,
|
||||
periodType,
|
||||
periodStartDate,
|
||||
periodEndDate,
|
||||
periodCountCalendarDays,
|
||||
periodDays,
|
||||
eventLength,
|
||||
minimumBookingNotice,
|
||||
workingHours,
|
||||
}: Omit<DatePickerProps, "weekStart" | "onDatePicked" | "date"> & {
|
||||
browsingDate: Dayjs;
|
||||
}
|
||||
) => {
|
||||
const date = browsingDate.startOf("day").date(day);
|
||||
return (
|
||||
isOutOfBounds(date, {
|
||||
periodType,
|
||||
periodStartDate,
|
||||
periodEndDate,
|
||||
periodCountCalendarDays,
|
||||
periodDays,
|
||||
}) ||
|
||||
!getSlots({
|
||||
inviteeDate: date,
|
||||
frequency: eventLength,
|
||||
minimumBookingNotice,
|
||||
workingHours,
|
||||
eventLength,
|
||||
}).length
|
||||
);
|
||||
};
|
||||
|
||||
const isDisabledRef = useRef(
|
||||
memoize(isDisabled, (day, { browsingDate }) => {
|
||||
// Make a composite cache key
|
||||
return day + "_" + browsingDate.toString();
|
||||
})
|
||||
);
|
||||
|
||||
const days = (() => {
|
||||
if (!browsingDate) {
|
||||
return [];
|
||||
}
|
||||
if (daysFromState) {
|
||||
return daysFromState;
|
||||
}
|
||||
// Create placeholder elements for empty days in first week
|
||||
let weekdayOfFirst = browsingDate.date(1).day();
|
||||
if (weekStart === "Monday") {
|
||||
weekdayOfFirst -= 1;
|
||||
if (weekdayOfFirst < 0) weekdayOfFirst = 6;
|
||||
}
|
||||
|
||||
const days = Array(weekdayOfFirst).fill(null);
|
||||
|
||||
const isDisabledMemoized = isDisabledRef.current;
|
||||
|
||||
const daysInMonth = browsingDate.daysInMonth();
|
||||
const daysInitialOffset = days.length;
|
||||
|
||||
// Build UI with All dates disabled
|
||||
for (let i = 1; i <= daysInMonth; i++) {
|
||||
days.push({
|
||||
disabled: true,
|
||||
date: i,
|
||||
});
|
||||
}
|
||||
|
||||
// Update dates with their availability
|
||||
doWorkAsync({
|
||||
batch: 1,
|
||||
name: "DatePicker",
|
||||
length: daysInMonth,
|
||||
callback: (i: number) => {
|
||||
const day = i + 1;
|
||||
days[daysInitialOffset + i] = {
|
||||
disabled: isDisabledMemoized(day, {
|
||||
browsingDate,
|
||||
periodType,
|
||||
periodStartDate,
|
||||
periodEndDate,
|
||||
periodCountCalendarDays,
|
||||
periodDays,
|
||||
eventLength,
|
||||
minimumBookingNotice,
|
||||
workingHours,
|
||||
}),
|
||||
date: day,
|
||||
};
|
||||
},
|
||||
batchDone: () => {
|
||||
setDays([...days]);
|
||||
},
|
||||
});
|
||||
|
||||
return days;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
})();
|
||||
|
||||
if (!browsingDate) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
// Handle month changes
|
||||
const incrementMonth = () => {
|
||||
setBrowsingDate(browsingDate?.add(1, "month"));
|
||||
};
|
||||
|
||||
const decrementMonth = () => {
|
||||
setBrowsingDate(browsingDate?.subtract(1, "month"));
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"mt-8 sm:mt-0 sm:min-w-[455px] " +
|
||||
(date
|
||||
? "w-full sm:w-1/2 sm:border-r sm:pl-4 sm:pr-6 sm:dark:border-gray-700 md:w-1/3 "
|
||||
: "w-full sm:pl-4")
|
||||
}>
|
||||
<div className="mb-4 flex text-xl font-light">
|
||||
<span className="w-1/2 dark:text-white">
|
||||
<strong className="text-bookingdarker dark:text-white">{month}</strong>{" "}
|
||||
<span className="text-bookinglight">{year}</span>
|
||||
</span>
|
||||
<div className="w-1/2 text-right dark:text-gray-400">
|
||||
<button
|
||||
onClick={decrementMonth}
|
||||
className={classNames(
|
||||
"group p-1 ltr:mr-2 rtl:ml-2",
|
||||
isFirstMonth && "text-bookinglighter dark:text-gray-600"
|
||||
)}
|
||||
disabled={isFirstMonth}
|
||||
data-testid="decrementMonth">
|
||||
<ChevronLeftIcon className="h-5 w-5 group-hover:text-black dark:group-hover:text-white" />
|
||||
</button>
|
||||
<button className="group p-1" onClick={incrementMonth} data-testid="incrementMonth">
|
||||
<ChevronRightIcon className="h-5 w-5 group-hover:text-black dark:group-hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-bookinglightest grid grid-cols-7 gap-4 border-t border-b text-center dark:border-gray-800 sm:border-0">
|
||||
{weekdayNames(i18n.language, weekStart === "Sunday" ? 0 : 1, "short").map((weekDay) => (
|
||||
<div key={weekDay} className="text-bookinglight my-4 text-xs uppercase tracking-widest">
|
||||
{weekDay}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="grid grid-cols-7 gap-2 text-center">
|
||||
{days.map((day, idx) => (
|
||||
<div
|
||||
key={day === null ? `e-${idx}` : `day-${day.date}`}
|
||||
style={{
|
||||
paddingTop: "100%",
|
||||
}}
|
||||
className="relative w-full">
|
||||
{day === null ? (
|
||||
<div key={`e-${idx}`} />
|
||||
) : (
|
||||
<button
|
||||
onClick={() => onDatePicked(browsingDate.date(day.date))}
|
||||
disabled={day.disabled}
|
||||
style={
|
||||
day.disabled ? { ...disabledDateButtonEmbedStyles } : { ...enabledDateButtonEmbedStyles }
|
||||
}
|
||||
className={classNames(
|
||||
"hover:border-brand disabled:text-bookinglighter absolute top-0 left-0 right-0 bottom-0 mx-auto w-full rounded-sm text-center font-medium hover:border disabled:cursor-default disabled:font-light disabled:hover:border-0 dark:hover:border-white",
|
||||
date && date.isSame(browsingDate.date(day.date), "day")
|
||||
? "bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast disabled:bg-gray-100 disabled:dark:bg-gray-600 disabled:dark:text-white"
|
||||
: ""
|
||||
)}
|
||||
data-testid="day"
|
||||
data-disabled={day.disabled}>
|
||||
{day.date}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DatePicker;
|
||||
@@ -1,64 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
interface WeekdaySelectProps {
|
||||
defaultValue: number[];
|
||||
onSelect: (selected: number[]) => void;
|
||||
}
|
||||
|
||||
export const WeekdaySelect = (props: WeekdaySelectProps) => {
|
||||
const { onSelect } = props;
|
||||
const [activeDays, setActiveDays] = useState<boolean[]>(
|
||||
Array.from(Array(7).keys()).map((v, i) => (props.defaultValue || []).includes(i))
|
||||
);
|
||||
|
||||
const days = ["S", "M", "T", "W", "T", "F", "S"];
|
||||
|
||||
useEffect(() => {
|
||||
onSelect(activeDays.map((v, idx) => (v ? idx : -1)).filter((v) => v !== -1));
|
||||
}, [onSelect, activeDays]);
|
||||
|
||||
const toggleDay = (idx: number) => {
|
||||
activeDays[idx] = !activeDays[idx];
|
||||
setActiveDays(([] as boolean[]).concat(activeDays));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="weekdaySelect">
|
||||
<div className="inline-flex">
|
||||
{days.map((day, idx) =>
|
||||
activeDays[idx] ? (
|
||||
<button
|
||||
key={idx}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
toggleDay(idx);
|
||||
}}
|
||||
className={`
|
||||
bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast
|
||||
h-10 w-10 rounded px-3 py-1 focus:outline-none
|
||||
${activeDays[idx + 1] ? "rounded-r-none" : ""}
|
||||
${activeDays[idx - 1] ? "rounded-l-none" : ""}
|
||||
${idx === 0 ? "rounded-l" : ""}
|
||||
${idx === days.length - 1 ? "rounded-r" : ""}
|
||||
`}>
|
||||
{day}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
key={idx}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
toggleDay(idx);
|
||||
}}
|
||||
style={{ marginTop: "1px", marginBottom: "1px" }}
|
||||
className={`h-10 w-10 rounded-none bg-gray-50 px-3 py-1 focus:outline-none ${
|
||||
idx === 0 ? "rounded-l" : "border-l-0"
|
||||
} ${idx === days.length - 1 ? "rounded-r" : ""}`}>
|
||||
{day}
|
||||
</button>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
import { Alert } from "@calcom/ui/Alert";
|
||||
|
||||
/**
|
||||
* @deprecated use `<Alert severity="error" message="x" />` instead
|
||||
*/
|
||||
export default function ErrorAlert(props: { message: string; className?: string }) {
|
||||
return <Alert severity="error" message={props.message} />;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Attendee } from "@prisma/client";
|
||||
import { TFunction } from "next-i18next";
|
||||
|
||||
import { Person } from "@calcom/types/Calendar";
|
||||
|
||||
export const attendeeToPersonConversionType = (attendees: Attendee[], t: TFunction): Person[] => {
|
||||
return attendees.map((attendee) => {
|
||||
return {
|
||||
name: attendee.name,
|
||||
email: attendee.email,
|
||||
timeZone: attendee.timeZone,
|
||||
locale: attendee.locale || "en",
|
||||
language: { translate: t, locale: attendee.locale || "en" },
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const COLOR_SCHEME_QUERY = "(prefers-color-scheme: dark)";
|
||||
|
||||
interface UseDarkModeOutput {
|
||||
isDarkMode: boolean;
|
||||
toggle: () => void;
|
||||
enable: () => void;
|
||||
disable: () => void;
|
||||
}
|
||||
|
||||
function useDarkMode(defaultValue?: boolean): UseDarkModeOutput {
|
||||
const getPrefersScheme = (): boolean => {
|
||||
// Prevents SSR issues
|
||||
if (process.browser) {
|
||||
return window.matchMedia(COLOR_SCHEME_QUERY).matches;
|
||||
}
|
||||
|
||||
return !!defaultValue;
|
||||
};
|
||||
|
||||
const [isDarkMode, setDarkMode] = useState<boolean>(getPrefersScheme());
|
||||
|
||||
// Update darkMode if os prefers changes
|
||||
useEffect(() => {
|
||||
const handler = () => setDarkMode(getPrefersScheme);
|
||||
const matchMedia = window.matchMedia(COLOR_SCHEME_QUERY);
|
||||
|
||||
matchMedia.addEventListener("change", handler);
|
||||
|
||||
return () => {
|
||||
matchMedia.removeEventListener("change", handler);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return {
|
||||
isDarkMode,
|
||||
toggle: () => setDarkMode((prev) => !prev),
|
||||
enable: () => setDarkMode(true),
|
||||
disable: () => setDarkMode(false),
|
||||
};
|
||||
}
|
||||
|
||||
export default useDarkMode;
|
||||
@@ -1,67 +0,0 @@
|
||||
import noop from "lodash/noop";
|
||||
|
||||
const data: Record<string, number> = {};
|
||||
/**
|
||||
* Starts an iteration from `0` to `length - 1` with batch size `batch`
|
||||
*
|
||||
* `callback` is called per iteration
|
||||
*
|
||||
* `done` is called when all iterations are done
|
||||
*
|
||||
* `name` is a unique identifier for the work. It allows the work that is not required to be dropped.
|
||||
*/
|
||||
export const doWorkAsync = ({
|
||||
length,
|
||||
name,
|
||||
callback,
|
||||
done,
|
||||
batch,
|
||||
offsetStart,
|
||||
batchDone,
|
||||
__pending,
|
||||
}: {
|
||||
name: string;
|
||||
length: number;
|
||||
callback: (i: number, b?: boolean) => void;
|
||||
done?: () => void;
|
||||
batchDone?: () => void;
|
||||
batch: number;
|
||||
offsetStart?: number;
|
||||
__pending?: boolean;
|
||||
}) => {
|
||||
offsetStart = offsetStart || 0;
|
||||
const stepLength = batch;
|
||||
const lastIndex = length - 1;
|
||||
const offsetEndExclusive = offsetStart + stepLength;
|
||||
|
||||
batchDone = batchDone || noop;
|
||||
done = done || noop;
|
||||
|
||||
if (!__pending && data[name]) {
|
||||
cancelAnimationFrame(data[name]);
|
||||
}
|
||||
|
||||
if (offsetStart >= length) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = offsetStart; i < offsetEndExclusive && i < length; i++) {
|
||||
callback(i, offsetEndExclusive > lastIndex);
|
||||
}
|
||||
|
||||
batchDone();
|
||||
|
||||
data[name] = requestAnimationFrame(() => {
|
||||
doWorkAsync({
|
||||
length,
|
||||
callback,
|
||||
batchDone,
|
||||
name,
|
||||
batch,
|
||||
done,
|
||||
offsetStart: offsetEndExclusive,
|
||||
__pending: true,
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
export interface Member {
|
||||
id: number;
|
||||
avatar: string | null;
|
||||
role: string;
|
||||
email: string;
|
||||
name: string | null;
|
||||
username: string | null;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
import { EventType, SchedulingType } from "@prisma/client";
|
||||
import { JSONObject } from "superjson/dist/types";
|
||||
|
||||
import { WorkingHours } from "./schedule";
|
||||
|
||||
export type AdvancedOptions = {
|
||||
metadata?: JSONObject;
|
||||
eventName?: string;
|
||||
periodType?: string;
|
||||
periodDays?: number;
|
||||
periodStartDate?: Date | string;
|
||||
periodEndDate?: Date | string;
|
||||
periodCountCalendarDays?: boolean;
|
||||
requiresConfirmation?: boolean;
|
||||
disableGuests?: boolean;
|
||||
minimumBookingNotice?: number;
|
||||
beforeBufferTime?: number;
|
||||
afterBufferTime?: number;
|
||||
slotInterval?: number | null;
|
||||
price?: number;
|
||||
currency?: string;
|
||||
schedulingType?: SchedulingType;
|
||||
users?: string[];
|
||||
availability?: { openingHours: WorkingHours[]; dateOverrides: WorkingHours[] };
|
||||
customInputs?: EventTypeCustomInput[];
|
||||
timeZone?: string;
|
||||
seatsPerTimeSlot: number;
|
||||
destinationCalendar?: {
|
||||
userId?: number;
|
||||
eventTypeId?: number;
|
||||
integration: string;
|
||||
externalId: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type EventTypeCustomInput = {
|
||||
id: number;
|
||||
label: string;
|
||||
placeholder: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type CreateEventType = {
|
||||
title: string;
|
||||
slug: string;
|
||||
description: string;
|
||||
length: number;
|
||||
teamId?: number;
|
||||
schedulingType?: SchedulingType;
|
||||
};
|
||||
|
||||
export type CreateEventTypeResponse = {
|
||||
eventType: EventType;
|
||||
};
|
||||
|
||||
export type EventTypeInput = AdvancedOptions & {
|
||||
id: number;
|
||||
title: string;
|
||||
slug: string;
|
||||
description: string;
|
||||
length: number;
|
||||
teamId?: number;
|
||||
hidden: boolean;
|
||||
locations: unknown;
|
||||
availability?: { openingHours: WorkingHours[]; dateOverrides: WorkingHours[] };
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
import { Webhook as PrismaWebhook } from "@prisma/client";
|
||||
|
||||
export type Webhook = PrismaWebhook & { prevState: null };
|
||||
@@ -408,11 +408,6 @@ hr {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.weekdaySelect button.active {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* react-date-picker forces a border upon us, cast it away */
|
||||
.react-date-picker__wrapper {
|
||||
border: none !important;
|
||||
|
||||
Reference in new issue
Block a user