cal.pub0.org/apps/web/pages/v2/availability/[schedule].tsx

189 lines
6.2 KiB
TypeScript
Raw Normal View History

V2 Main (#3549) * Fix breadcrumb colors * HorizontalTabs * Team List Item WIP * Horizontal Tabs * Cards * Remove team list item WIP * Login Page * Add welcome back i118n * EventType page work * Update EventType Icons * WIP Availability * Horizontal Tab Work * Add build command for in root * Update build DIr/command * Add Edit Button + change buttons to v2 * Availablitiy page * Fix IPAD * Make mobile look a little nicer * WIP bookingshell * Remove list items from breaking build * Mian bulk of Booking Page. * Few updates to components * Fix chormatic feedback * Fix banner * Fix Empty Screen * Text area + embded window fixes * Semi fix avatar * Troubleshoot container + Active on count * Improve mobile * NITS * Fix padding on input * Fix icons * Starting to move event types settings to tabs * Begin migration to single page form * Single page tabs * Limits Page * Advanced tab * Add RHF to dependancies * Most of advanced tab * Solved RHF mismtach * Build fixes * RHF conditionals fixes * Improved legibility * Major refactor/organisation into optional V2 UI * Portal EditLocationModal * Fix dialoug form * Update imports * Auto Animate + custom inputs WIP * Custom Inputs * WIP Apps * Fixing stories imports * Stripe app * Remove duplicate dialog * Remove duplicate dialog * Fix embed URL * Fix app toggles + number of active apps * Fix container padding on disabledBorder prop * Removes strict * EventType Team page WIP * Fix embed * NIT * Add Darkmode gray color * V2 Shell WIP * Fix headings on shell V2 * Fix mobile layout with V2 shell * V2 create event type button * Checked Team Select * Hidden to happen on save - not on toggle * Team Attendee Select animation * Fix scheduling type and remove multi select label * Fix overflow on teams url * Even Type move order handles * Fix Embed TS errors * Fix TS errors * Fix Eslint errors * Fix TS errors for UI * Fix ESLINT error * added SidebarCard for promo to v2 and storybook (#3906) Co-authored-by: Julian Benegas <julianbenegas99@gmail.com> Co-authored-by: Alan <alannnc@gmail.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> * Tooltip Provider - Wrapper due to dep upgrade * public event type list darkmode * V2 Color changes to public booking * Remove unused component * Fix typecheck * Removed extra buttons on create ET dialog * ET edit page refactoring * Avoids form wrapping the whole Shell * Nitpicks Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: Julian Benegas <julianbenegas99@gmail.com> Co-authored-by: Alan <alannnc@gmail.com>
2022-08-24 20:18:42 +00:00
import { GetStaticPaths, GetStaticProps } from "next";
import { useRouter } from "next/router";
import { useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { z } from "zod";
import { DEFAULT_SCHEDULE, availabilityAsString } from "@calcom/lib/availability";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { stringOrNumber } from "@calcom/prisma/zod-utils";
import { inferQueryOutput, trpc } from "@calcom/trpc/react";
import { BadgeCheckIcon } from "@calcom/ui/Icon";
import Shell from "@calcom/ui/Shell";
import TimezoneSelect from "@calcom/ui/form/TimezoneSelect";
import { Button, Switch, Schedule, Form, TextField, showToast } from "@calcom/ui/v2";
import { QueryCell } from "@lib/QueryCell";
import { HttpError } from "@lib/core/http/error";
import EditableHeading from "@components/ui/EditableHeading";
export function AvailabilityForm(props: inferQueryOutput<"viewer.availability.schedule">) {
const { t } = useLocale();
const router = useRouter();
const utils = trpc.useContext();
const form = useForm({
defaultValues: {
schedule: props.availability || DEFAULT_SCHEDULE,
isDefault: !!props.isDefault,
timeZone: props.timeZone,
},
});
const updateMutation = trpc.useMutation("viewer.availability.schedule.update", {
onSuccess: async ({ schedule }) => {
await utils.invalidateQueries(["viewer.availability.schedule"]);
await router.push("/availability");
showToast(
t("availability_updated_successfully", {
scheduleName: schedule.name,
}),
"success"
);
},
onError: (err) => {
if (err instanceof HttpError) {
const message = `${err.statusCode}: ${err.message}`;
showToast(message, "error");
}
},
});
return (
<Form
form={form}
handleSubmit={async (values) => {
updateMutation.mutate({
scheduleId: parseInt(router.query.schedule as string, 10),
name: props.schedule.name,
...values,
});
}}
className="-mx-5 flex flex-col sm:mx-0 xl:flex-row">
<div className="flex-1">
<div className="divide-y rounded-md border border-gray-200 bg-white px-4 py-5 sm:p-6">
<h3 className="mb-5 text-base font-medium leading-6 text-gray-900">{t("change_start_end")}</h3>
<Schedule name="schedule" />
</div>
<div className="space-x-2 pt-4 text-right sm:pt-2">
<Button color="secondary" href="/availability" tabIndex={-1}>
{t("cancel")}
</Button>
<Button>{t("save")}</Button>
</div>
</div>
<div className="min-w-40 col-span-3 ml-2 space-y-2 lg:col-span-1">
{props.isDefault ? (
<span className="flex items-center">
<BadgeCheckIcon className="mr-1 h-4 w-4" /> {t("default")}
</span>
) : (
<Controller
name="isDefault"
render={({ field: { onChange, value } }) => (
<Switch label={t("set_to_default")} onCheckedChange={onChange} checked={value} />
)}
/>
)}
<div className="xl:max-w-80 w-full">
<div>
<label htmlFor="timeZone" className="block text-sm font-medium text-gray-700">
{t("timezone")}
</label>
<div className="mt-1">
<Controller
name="timeZone"
render={({ field: { onChange, value } }) => (
<TimezoneSelect
value={value}
className="focus:border-brand mt-1 block w-full rounded-md border-gray-300 text-sm"
onChange={(timezone) => onChange(timezone.value)}
/>
)}
/>
</div>
</div>
<div className="pt-6">
<TextField
name="aciveOn"
label={t("active_on")}
disabled
value={t("nr_event_type_other", { count: props.schedule.eventType?.length })}
className="focus:border-brand mt-1 block w-full rounded-md border-gray-300 text-sm"
/>
</div>
<div className="mt-6 rounded-md border border-gray-200 px-4 py-5 sm:p-6">
<h3 className="text-base font-medium leading-6 text-gray-900">
{t("something_doesnt_look_right")}
</h3>
<div className="mt-2 max-w-xl text-sm text-gray-500">
<p>{t("troubleshoot_availability")}</p>
</div>
<div className="mt-5">
<Button href="/availability/troubleshoot" color="secondary">
{t("launch_troubleshooter")}
</Button>
</div>
</div>
</div>
</div>
</Form>
);
}
const querySchema = z.object({
schedule: stringOrNumber,
});
export default function Availability() {
const router = useRouter();
const { i18n } = useLocale();
const { schedule: scheduleId } = router.isReady ? querySchema.parse(router.query) : { schedule: -1 };
const query = trpc.useQuery(["viewer.availability.schedule", { scheduleId }], { enabled: router.isReady });
const [name, setName] = useState<string>();
return (
<div>
<QueryCell
query={query}
success={({ data }) => {
return (
<Shell
heading={<EditableHeading title={name || data.schedule.name} onChange={setName} />}
subtitle={data.schedule.availability.map((availability) => (
<span key={availability.id}>
{availabilityAsString(availability, i18n.language)}
<br />
</span>
))}>
<AvailabilityForm
{...{ ...data, schedule: { ...data.schedule, name: name || data.schedule.name } }}
/>
</Shell>
);
}}
/>
</div>
);
}
export const getStaticProps: GetStaticProps = (ctx) => {
const params = querySchema.safeParse(ctx.params);
if (!params.success) return { notFound: true };
return {
props: {
schedule: params.data.schedule,
},
revalidate: 10, // seconds
};
};
export const getStaticPaths: GetStaticPaths = () => {
return {
paths: [],
fallback: "blocking",
};
};