2021-09-22 19:52:38 +00:00
|
|
|
import { ClockIcon } from "@heroicons/react/outline";
|
2021-07-18 13:12:18 +00:00
|
|
|
import Link from "next/link";
|
|
|
|
import { useRouter } from "next/router";
|
2021-09-30 21:37:52 +00:00
|
|
|
import { useEffect } from "react";
|
|
|
|
import { useForm } from "react-hook-form";
|
2021-09-22 19:52:38 +00:00
|
|
|
|
2021-10-13 10:49:15 +00:00
|
|
|
import { useLocale } from "@lib/hooks/useLocale";
|
2021-09-30 21:37:52 +00:00
|
|
|
import { useToggleQuery } from "@lib/hooks/useToggleQuery";
|
|
|
|
import showToast from "@lib/notification";
|
2021-09-27 14:47:55 +00:00
|
|
|
import { trpc } from "@lib/trpc";
|
2021-09-22 19:52:38 +00:00
|
|
|
|
2021-09-30 21:37:52 +00:00
|
|
|
import { Dialog, DialogContent } from "@components/Dialog";
|
2021-09-22 19:52:38 +00:00
|
|
|
import Loader from "@components/Loader";
|
|
|
|
import Shell from "@components/Shell";
|
2021-09-27 14:47:55 +00:00
|
|
|
import { Alert } from "@components/ui/Alert";
|
2021-09-30 21:37:52 +00:00
|
|
|
import Button from "@components/ui/Button";
|
|
|
|
|
|
|
|
function convertMinsToHrsMins(mins: number) {
|
|
|
|
const h = Math.floor(mins / 60);
|
|
|
|
const m = mins % 60;
|
|
|
|
const hours = h < 10 ? "0" + h : h;
|
|
|
|
const minutes = m < 10 ? "0" + m : m;
|
|
|
|
return `${hours}:${minutes}`;
|
|
|
|
}
|
2021-09-27 14:47:55 +00:00
|
|
|
export default function Availability() {
|
2021-10-13 10:49:15 +00:00
|
|
|
const { t } = useLocale();
|
2021-09-27 14:47:55 +00:00
|
|
|
const queryMe = trpc.useQuery(["viewer.me"]);
|
2021-09-30 21:37:52 +00:00
|
|
|
const formModal = useToggleQuery("edit");
|
|
|
|
|
|
|
|
const formMethods = useForm<{
|
|
|
|
startHours: string;
|
|
|
|
startMins: string;
|
|
|
|
endHours: string;
|
|
|
|
endMins: string;
|
|
|
|
bufferHours: string;
|
|
|
|
bufferMins: string;
|
|
|
|
}>({});
|
2021-07-18 13:12:18 +00:00
|
|
|
const router = useRouter();
|
2021-04-29 13:04:08 +00:00
|
|
|
|
2021-09-30 21:37:52 +00:00
|
|
|
useEffect(() => {
|
|
|
|
/**
|
|
|
|
* This hook populates the form with new values as soon as the user is loaded or changes
|
|
|
|
*/
|
|
|
|
const user = queryMe.data;
|
|
|
|
if (formMethods.formState.isDirty || !user) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
formMethods.reset({
|
|
|
|
startHours: convertMinsToHrsMins(user.startTime).split(":")[0],
|
|
|
|
startMins: convertMinsToHrsMins(user.startTime).split(":")[1],
|
|
|
|
endHours: convertMinsToHrsMins(user.endTime).split(":")[0],
|
|
|
|
endMins: convertMinsToHrsMins(user.endTime).split(":")[1],
|
|
|
|
bufferHours: convertMinsToHrsMins(user.bufferTime).split(":")[0],
|
|
|
|
bufferMins: convertMinsToHrsMins(user.bufferTime).split(":")[1],
|
|
|
|
});
|
|
|
|
}, [formMethods, queryMe.data]);
|
2021-04-13 16:16:32 +00:00
|
|
|
|
2021-09-27 14:47:55 +00:00
|
|
|
if (queryMe.status === "loading") {
|
2021-08-05 11:36:24 +00:00
|
|
|
return <Loader />;
|
2021-07-18 13:12:18 +00:00
|
|
|
}
|
2021-09-27 14:47:55 +00:00
|
|
|
if (queryMe.status !== "success") {
|
2021-10-13 10:49:15 +00:00
|
|
|
return <Alert severity="error" title={t("something_went_wrong")} />;
|
2021-09-27 14:47:55 +00:00
|
|
|
}
|
|
|
|
const user = queryMe.data;
|
2021-04-08 14:20:38 +00:00
|
|
|
|
2021-07-18 13:12:18 +00:00
|
|
|
return (
|
|
|
|
<div>
|
2021-10-13 10:49:15 +00:00
|
|
|
<Shell heading={t("availability")} subtitle={t("configure_availability")}>
|
2021-07-18 13:12:18 +00:00
|
|
|
<div className="flex">
|
2021-08-05 11:36:24 +00:00
|
|
|
<div className="w-1/2 mr-2 bg-white border border-gray-200 rounded-sm">
|
2021-07-18 13:12:18 +00:00
|
|
|
<div className="px-4 py-5 sm:p-6">
|
2021-10-13 10:49:15 +00:00
|
|
|
<h3 className="text-lg leading-6 font-medium text-gray-900">{t("change_start_end")}</h3>
|
2021-07-18 13:12:18 +00:00
|
|
|
<div className="mt-2 max-w-xl text-sm text-gray-500">
|
|
|
|
<p>
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("current_start_date")} {convertMinsToHrsMins(user.startTime)} {t("and_end_at")}{" "}
|
2021-09-27 14:47:55 +00:00
|
|
|
{convertMinsToHrsMins(user.endTime)}.
|
2021-07-18 13:12:18 +00:00
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div className="mt-5">
|
2021-10-13 10:49:15 +00:00
|
|
|
<Button href={formModal.hrefOn}>{t("change_available_times")}</Button>
|
2021-07-18 13:12:18 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2021-08-05 11:36:24 +00:00
|
|
|
<div className="w-1/2 ml-2 border border-gray-200 rounded-sm">
|
2021-07-18 13:12:18 +00:00
|
|
|
<div className="px-4 py-5 sm:p-6">
|
|
|
|
<h3 className="text-lg leading-6 font-medium text-gray-900">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("something_doesnt_look_right")}
|
2021-07-18 13:12:18 +00:00
|
|
|
</h3>
|
|
|
|
<div className="mt-2 max-w-xl text-sm text-gray-500">
|
2021-10-13 10:49:15 +00:00
|
|
|
<p>{t("troubleshoot_availability")}</p>
|
2021-07-18 13:12:18 +00:00
|
|
|
</div>
|
|
|
|
<div className="mt-5">
|
|
|
|
<Link href="/availability/troubleshoot">
|
2021-10-13 10:49:15 +00:00
|
|
|
<a className="btn btn-white">{t("launch_troubleshooter")}</a>
|
2021-07-18 13:12:18 +00:00
|
|
|
</Link>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-04-08 14:20:38 +00:00
|
|
|
|
2021-09-30 21:37:52 +00:00
|
|
|
<Dialog
|
|
|
|
open={formModal.isOn}
|
|
|
|
onOpenChange={(isOpen) => {
|
|
|
|
router.push(isOpen ? formModal.hrefOn : formModal.hrefOff);
|
|
|
|
}}>
|
|
|
|
<DialogContent>
|
|
|
|
<div className="sm:flex sm:items-start mb-4">
|
|
|
|
<div className="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-neutral-100 sm:mx-0 sm:h-10 sm:w-10">
|
|
|
|
<ClockIcon className="h-6 w-6 text-neutral-600" />
|
|
|
|
</div>
|
|
|
|
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
|
|
|
<h3 className="text-lg leading-6 font-medium text-gray-900" id="modal-title">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("change_your_available_times")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</h3>
|
|
|
|
<div>
|
2021-10-13 10:49:15 +00:00
|
|
|
<p className="text-sm text-gray-500">{t("change_start_end_buffer")}</p>
|
2021-07-18 13:12:18 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-09-30 21:37:52 +00:00
|
|
|
<form
|
|
|
|
onSubmit={formMethods.handleSubmit(async (values) => {
|
|
|
|
const startMins = parseInt(values.startHours) * 60 + parseInt(values.startMins);
|
|
|
|
const endMins = parseInt(values.endHours) * 60 + parseInt(values.endMins);
|
|
|
|
const bufferMins = parseInt(values.bufferHours) * 60 + parseInt(values.bufferMins);
|
|
|
|
|
|
|
|
// TODO: Add validation
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
const response = await fetch("/api/availability/day", {
|
|
|
|
method: "PATCH",
|
|
|
|
body: JSON.stringify({ start: startMins, end: endMins, buffer: bufferMins }),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
|
|
|
});
|
|
|
|
if (!response.ok) {
|
2021-10-13 10:49:15 +00:00
|
|
|
showToast(t("something_went_wrong"), "error");
|
2021-09-30 21:37:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
await queryMe.refetch();
|
|
|
|
router.push(formModal.hrefOff);
|
|
|
|
|
2021-10-13 10:49:15 +00:00
|
|
|
showToast(t("start_end_changed_successfully"), "success");
|
2021-09-30 21:37:52 +00:00
|
|
|
})}>
|
|
|
|
<div className="flex mb-4">
|
2021-10-13 10:49:15 +00:00
|
|
|
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">
|
|
|
|
{t("start_time")}
|
|
|
|
</label>
|
2021-09-30 21:37:52 +00:00
|
|
|
<div>
|
|
|
|
<label htmlFor="startHours" className="sr-only">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("hours")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</label>
|
|
|
|
<input
|
|
|
|
{...formMethods.register("startHours")}
|
|
|
|
id="startHours"
|
|
|
|
type="number"
|
|
|
|
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
|
|
placeholder="9"
|
|
|
|
defaultValue={convertMinsToHrsMins(user.startTime).split(":")[0]}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<span className="mx-2 pt-1">:</span>
|
|
|
|
<div>
|
|
|
|
<label htmlFor="startMins" className="sr-only">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("minutes")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</label>
|
|
|
|
<input
|
|
|
|
{...formMethods.register("startMins")}
|
|
|
|
id="startMins"
|
|
|
|
type="number"
|
|
|
|
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
|
|
placeholder="30"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="flex mb-4">
|
2021-10-13 10:49:15 +00:00
|
|
|
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">{t("end_time")}</label>
|
2021-09-30 21:37:52 +00:00
|
|
|
<div>
|
|
|
|
<label htmlFor="endHours" className="sr-only">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("hours")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</label>
|
|
|
|
<input
|
|
|
|
{...formMethods.register("endHours")}
|
|
|
|
type="number"
|
|
|
|
id="endHours"
|
|
|
|
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
|
|
placeholder="17"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<span className="mx-2 pt-1">:</span>
|
|
|
|
<div>
|
|
|
|
<label htmlFor="endMins" className="sr-only">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("minutes")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</label>
|
|
|
|
<input
|
|
|
|
{...formMethods.register("endMins")}
|
|
|
|
type="number"
|
|
|
|
id="endMins"
|
|
|
|
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
|
|
placeholder="30"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="flex mb-4">
|
2021-10-13 10:49:15 +00:00
|
|
|
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">{t("buffer")}</label>
|
2021-09-30 21:37:52 +00:00
|
|
|
<div>
|
|
|
|
<label htmlFor="bufferHours" className="sr-only">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("hours")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</label>
|
|
|
|
<input
|
|
|
|
{...formMethods.register("bufferHours")}
|
|
|
|
type="number"
|
|
|
|
id="bufferHours"
|
|
|
|
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
|
|
placeholder="0"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<span className="mx-2 pt-1">:</span>
|
|
|
|
<div>
|
|
|
|
<label htmlFor="bufferMins" className="sr-only">
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("minutes")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</label>
|
|
|
|
<input
|
|
|
|
{...formMethods.register("bufferMins")}
|
|
|
|
type="number"
|
|
|
|
id="bufferMins"
|
|
|
|
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
|
|
placeholder="10"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="mt-5 sm:mt-4 sm:flex space-x-2">
|
|
|
|
<Button href={formModal.hrefOff} color="secondary" tabIndex={-1}>
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("cancel")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</Button>
|
|
|
|
<Button type="submit" loading={formMethods.formState.isSubmitting}>
|
2021-10-13 10:49:15 +00:00
|
|
|
{t("update")}
|
2021-09-30 21:37:52 +00:00
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</DialogContent>
|
|
|
|
</Dialog>
|
2021-07-18 13:12:18 +00:00
|
|
|
</Shell>
|
|
|
|
</div>
|
|
|
|
);
|
2021-04-08 14:20:38 +00:00
|
|
|
}
|