refactor availability times form using react-hook-form (#824)
* use toast * use `Button` * make fn * rewrite with react-hook-form * add comment * fix deps Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
parent
60298f6eeb
commit
30163f0a78
3 changed files with 192 additions and 246 deletions
|
@ -28,6 +28,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^1.4.1",
|
"@headlessui/react": "^1.4.1",
|
||||||
"@heroicons/react": "^1.0.4",
|
"@heroicons/react": "^1.0.4",
|
||||||
|
"@hookform/resolvers": "^2.8.1",
|
||||||
"@jitsu/sdk-js": "^2.2.4",
|
"@jitsu/sdk-js": "^2.2.4",
|
||||||
"@prisma/client": "^2.30.2",
|
"@prisma/client": "^2.30.2",
|
||||||
"@radix-ui/react-avatar": "^0.1.0",
|
"@radix-ui/react-avatar": "^0.1.0",
|
||||||
|
@ -73,6 +74,7 @@
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-easy-crop": "^3.5.2",
|
"react-easy-crop": "^3.5.2",
|
||||||
|
"react-hook-form": "^7.16.1",
|
||||||
"react-hot-toast": "^2.1.0",
|
"react-hot-toast": "^2.1.0",
|
||||||
"react-intl": "^5.20.7",
|
"react-intl": "^5.20.7",
|
||||||
"react-multi-email": "^0.5.3",
|
"react-multi-email": "^0.5.3",
|
||||||
|
|
|
@ -1,36 +1,57 @@
|
||||||
import { ClockIcon } from "@heroicons/react/outline";
|
import { ClockIcon } from "@heroicons/react/outline";
|
||||||
import { useSession } from "next-auth/client";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useRef, useState } from "react";
|
import { useEffect } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
|
import { useToggleQuery } from "@lib/hooks/useToggleQuery";
|
||||||
|
import showToast from "@lib/notification";
|
||||||
import { trpc } from "@lib/trpc";
|
import { trpc } from "@lib/trpc";
|
||||||
|
|
||||||
|
import { Dialog, DialogContent } from "@components/Dialog";
|
||||||
import Loader from "@components/Loader";
|
import Loader from "@components/Loader";
|
||||||
import Modal from "@components/Modal";
|
|
||||||
import Shell from "@components/Shell";
|
import Shell from "@components/Shell";
|
||||||
import { Alert } from "@components/ui/Alert";
|
import { Alert } from "@components/ui/Alert";
|
||||||
|
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}`;
|
||||||
|
}
|
||||||
export default function Availability() {
|
export default function Availability() {
|
||||||
const queryMe = trpc.useQuery(["viewer.me"]);
|
const queryMe = trpc.useQuery(["viewer.me"]);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const formModal = useToggleQuery("edit");
|
||||||
const [session, loading] = useSession();
|
|
||||||
const router = useRouter();
|
|
||||||
const [showAddModal, setShowAddModal] = useState(false);
|
|
||||||
const [successModalOpen, setSuccessModalOpen] = useState(false);
|
|
||||||
const [showChangeTimesModal, setShowChangeTimesModal] = useState(false);
|
|
||||||
const titleRef = useRef<HTMLInputElement>();
|
|
||||||
const slugRef = useRef<HTMLInputElement>();
|
|
||||||
const descriptionRef = useRef<HTMLTextAreaElement>();
|
|
||||||
const lengthRef = useRef<HTMLInputElement>();
|
|
||||||
const isHiddenRef = useRef<HTMLInputElement>();
|
|
||||||
|
|
||||||
const startHoursRef = useRef<HTMLInputElement>();
|
const formMethods = useForm<{
|
||||||
const startMinsRef = useRef<HTMLInputElement>();
|
startHours: string;
|
||||||
const endHoursRef = useRef<HTMLInputElement>();
|
startMins: string;
|
||||||
const endMinsRef = useRef<HTMLInputElement>();
|
endHours: string;
|
||||||
const bufferHoursRef = useRef<HTMLInputElement>();
|
endMins: string;
|
||||||
const bufferMinsRef = useRef<HTMLInputElement>();
|
bufferHours: string;
|
||||||
|
bufferMins: string;
|
||||||
|
}>({});
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
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]);
|
||||||
|
|
||||||
if (queryMe.status === "loading") {
|
if (queryMe.status === "loading") {
|
||||||
return <Loader />;
|
return <Loader />;
|
||||||
|
@ -40,86 +61,6 @@ export default function Availability() {
|
||||||
}
|
}
|
||||||
const user = queryMe.data;
|
const user = queryMe.data;
|
||||||
|
|
||||||
function toggleAddModal() {
|
|
||||||
setShowAddModal(!showAddModal);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleChangeTimesModal() {
|
|
||||||
setShowChangeTimesModal(!showChangeTimesModal);
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeSuccessModal = () => {
|
|
||||||
setSuccessModalOpen(false);
|
|
||||||
router.replace(router.asPath);
|
|
||||||
};
|
|
||||||
|
|
||||||
function convertMinsToHrsMins(mins) {
|
|
||||||
let h = Math.floor(mins / 60);
|
|
||||||
let m = mins % 60;
|
|
||||||
h = h < 10 ? "0" + h : h;
|
|
||||||
m = m < 10 ? "0" + m : m;
|
|
||||||
return `${h}:${m}`;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
async function createEventTypeHandler(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const enteredTitle = titleRef.current.value;
|
|
||||||
const enteredSlug = slugRef.current.value;
|
|
||||||
const enteredDescription = descriptionRef.current.value;
|
|
||||||
const enteredLength = lengthRef.current.value;
|
|
||||||
const enteredIsHidden = isHiddenRef.current.checked;
|
|
||||||
|
|
||||||
// TODO: Add validation
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const response = await fetch("/api/availability/eventtype", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
title: enteredTitle,
|
|
||||||
slug: enteredSlug,
|
|
||||||
description: enteredDescription,
|
|
||||||
length: enteredLength,
|
|
||||||
hidden: enteredIsHidden,
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (enteredTitle && enteredLength) {
|
|
||||||
router.replace(router.asPath);
|
|
||||||
toggleAddModal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateStartEndTimesHandler(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const enteredStartHours = parseInt(startHoursRef.current.value);
|
|
||||||
const enteredStartMins = parseInt(startMinsRef.current.value);
|
|
||||||
const enteredEndHours = parseInt(endHoursRef.current.value);
|
|
||||||
const enteredEndMins = parseInt(endMinsRef.current.value);
|
|
||||||
const enteredBufferHours = parseInt(bufferHoursRef.current.value);
|
|
||||||
const enteredBufferMins = parseInt(bufferMinsRef.current.value);
|
|
||||||
|
|
||||||
const startMins = enteredStartHours * 60 + enteredStartMins;
|
|
||||||
const endMins = enteredEndHours * 60 + enteredEndMins;
|
|
||||||
const bufferMins = enteredBufferHours * 60 + enteredBufferMins;
|
|
||||||
|
|
||||||
// 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",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
setShowChangeTimesModal(false);
|
|
||||||
setSuccessModalOpen(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Shell heading="Availability" subtitle="Configure times when you are available for bookings.">
|
<Shell heading="Availability" subtitle="Configure times when you are available for bookings.">
|
||||||
|
@ -136,9 +77,7 @@ export default function Availability() {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
<button onClick={toggleChangeTimesModal} type="button" className="btn btn-primary">
|
<Button href={formModal.hrefOn}>Change available times</Button>
|
||||||
Change available times
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -159,153 +98,148 @@ export default function Availability() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{showChangeTimesModal && (
|
|
||||||
<div
|
|
||||||
className="fixed z-50 inset-0 overflow-y-auto"
|
|
||||||
aria-labelledby="modal-title"
|
|
||||||
role="dialog"
|
|
||||||
aria-modal="true">
|
|
||||||
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
|
|
||||||
<div
|
|
||||||
className="fixed inset-0 bg-gray-500 z-0 bg-opacity-75 transition-opacity"
|
|
||||||
aria-hidden="true"></div>
|
|
||||||
|
|
||||||
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">
|
<Dialog
|
||||||
​
|
open={formModal.isOn}
|
||||||
</span>
|
onOpenChange={(isOpen) => {
|
||||||
|
router.push(isOpen ? formModal.hrefOn : formModal.hrefOff);
|
||||||
<div className="inline-block align-bottom bg-white rounded-sm px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
|
}}>
|
||||||
<div className="sm:flex sm:items-start mb-4">
|
<DialogContent>
|
||||||
<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">
|
<div className="sm:flex sm:items-start mb-4">
|
||||||
<ClockIcon className="h-6 w-6 text-neutral-600" />
|
<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">
|
||||||
</div>
|
<ClockIcon className="h-6 w-6 text-neutral-600" />
|
||||||
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
</div>
|
||||||
<h3 className="text-lg leading-6 font-medium text-gray-900" id="modal-title">
|
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||||
Change your available times
|
<h3 className="text-lg leading-6 font-medium text-gray-900" id="modal-title">
|
||||||
</h3>
|
Change your available times
|
||||||
<div>
|
</h3>
|
||||||
<p className="text-sm text-gray-500">
|
<div>
|
||||||
Set the start and end time of your day and a minimum buffer between your meetings.
|
<p className="text-sm text-gray-500">
|
||||||
</p>
|
Set the start and end time of your day and a minimum buffer between your meetings.
|
||||||
</div>
|
</p>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<form onSubmit={updateStartEndTimesHandler}>
|
|
||||||
<div className="flex mb-4">
|
|
||||||
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">Start time</label>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="hours" className="sr-only">
|
|
||||||
Hours
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
ref={startHoursRef}
|
|
||||||
type="number"
|
|
||||||
name="hours"
|
|
||||||
id="hours"
|
|
||||||
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="minutes" className="sr-only">
|
|
||||||
Minutes
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
ref={startMinsRef}
|
|
||||||
type="number"
|
|
||||||
name="minutes"
|
|
||||||
id="minutes"
|
|
||||||
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
||||||
placeholder="30"
|
|
||||||
defaultValue={convertMinsToHrsMins(user.startTime).split(":")[1]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex mb-4">
|
|
||||||
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">End time</label>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="hours" className="sr-only">
|
|
||||||
Hours
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
ref={endHoursRef}
|
|
||||||
type="number"
|
|
||||||
name="hours"
|
|
||||||
id="hours"
|
|
||||||
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
||||||
placeholder="17"
|
|
||||||
defaultValue={convertMinsToHrsMins(user.endTime).split(":")[0]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span className="mx-2 pt-1">:</span>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="minutes" className="sr-only">
|
|
||||||
Minutes
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
ref={endMinsRef}
|
|
||||||
type="number"
|
|
||||||
name="minutes"
|
|
||||||
id="minutes"
|
|
||||||
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
||||||
placeholder="30"
|
|
||||||
defaultValue={convertMinsToHrsMins(user.endTime).split(":")[1]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex mb-4">
|
|
||||||
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">Buffer</label>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="hours" className="sr-only">
|
|
||||||
Hours
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
ref={bufferHoursRef}
|
|
||||||
type="number"
|
|
||||||
name="hours"
|
|
||||||
id="hours"
|
|
||||||
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
||||||
placeholder="0"
|
|
||||||
defaultValue={convertMinsToHrsMins(user.bufferTime).split(":")[0]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span className="mx-2 pt-1">:</span>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="minutes" className="sr-only">
|
|
||||||
Minutes
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
ref={bufferMinsRef}
|
|
||||||
type="number"
|
|
||||||
name="minutes"
|
|
||||||
id="minutes"
|
|
||||||
className="shadow-sm focus:ring-neutral-500 focus:border-neutral-500 block w-full sm:text-sm border-gray-300 rounded-sm"
|
|
||||||
placeholder="10"
|
|
||||||
defaultValue={convertMinsToHrsMins(user.bufferTime).split(":")[1]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
|
||||||
<button type="submit" className="btn btn-primary">
|
|
||||||
Update
|
|
||||||
</button>
|
|
||||||
<button onClick={toggleChangeTimesModal} type="button" className="btn btn-white mr-2">
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<form
|
||||||
)}
|
onSubmit={formMethods.handleSubmit(async (values) => {
|
||||||
<Modal
|
const startMins = parseInt(values.startHours) * 60 + parseInt(values.startMins);
|
||||||
heading="Start and end times changed"
|
const endMins = parseInt(values.endHours) * 60 + parseInt(values.endMins);
|
||||||
description="The start and end times for your day have been changed successfully."
|
const bufferMins = parseInt(values.bufferHours) * 60 + parseInt(values.bufferMins);
|
||||||
open={successModalOpen}
|
|
||||||
handleClose={closeSuccessModal}
|
// 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) {
|
||||||
|
showToast("Something went wrong", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await queryMe.refetch();
|
||||||
|
router.push(formModal.hrefOff);
|
||||||
|
|
||||||
|
showToast("The start and end times for your day have been changed successfully.", "success");
|
||||||
|
})}>
|
||||||
|
<div className="flex mb-4">
|
||||||
|
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">Start time</label>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="startHours" className="sr-only">
|
||||||
|
Hours
|
||||||
|
</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">
|
||||||
|
Minutes
|
||||||
|
</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">
|
||||||
|
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">End time</label>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="endHours" className="sr-only">
|
||||||
|
Hours
|
||||||
|
</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">
|
||||||
|
Minutes
|
||||||
|
</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">
|
||||||
|
<label className="w-1/4 pt-2 block text-sm font-medium text-gray-700">Buffer</label>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="bufferHours" className="sr-only">
|
||||||
|
Hours
|
||||||
|
</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">
|
||||||
|
Minutes
|
||||||
|
</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}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" loading={formMethods.formState.isSubmitting}>
|
||||||
|
Update
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</Shell>
|
</Shell>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -548,6 +548,11 @@
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/@heroicons/react/-/react-1.0.4.tgz"
|
resolved "https://registry.npmjs.org/@heroicons/react/-/react-1.0.4.tgz"
|
||||||
|
|
||||||
|
"@hookform/resolvers@^2.8.1":
|
||||||
|
version "2.8.1"
|
||||||
|
resolved "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-2.8.1.tgz#0d4fdd25bdeb4b98bf4e177c63fc4efa173454dd"
|
||||||
|
integrity sha512-U5lgaCkvD+0e5X8iQmCHiF+jOqjTX6OHUA7zPdeIHI6xdAOoi3rH9MKNuwMwv5Hly2LL6XtDgDkS/k+YG9hOew==
|
||||||
|
|
||||||
"@humanwhocodes/config-array@^0.5.0":
|
"@humanwhocodes/config-array@^0.5.0":
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz"
|
resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz"
|
||||||
|
@ -6462,6 +6467,11 @@ react-fit@^1.0.3:
|
||||||
detect-element-overflow "^1.2.0"
|
detect-element-overflow "^1.2.0"
|
||||||
prop-types "^15.6.0"
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
|
react-hook-form@^7.16.1:
|
||||||
|
version "7.16.1"
|
||||||
|
resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.16.1.tgz#669046df378a71949e5cf8a2398cbe20d5cb27bc"
|
||||||
|
integrity sha512-kcLDmSmlyLUFx2UU5bG/o4+3NeK753fhKodJa8gkplXohGkpAq0/p+TR24OWjZmkEc3ES7ppC5v5d6KUk+fJTA==
|
||||||
|
|
||||||
react-hot-toast@^2.1.0:
|
react-hot-toast@^2.1.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.1.1.tgz"
|
resolved "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.1.1.tgz"
|
||||||
|
|
Loading…
Reference in a new issue