import { useCallback, useContext } from "react"; import { Button, Col, Form, Modal, Row } from "react-bootstrap"; import { useForm, useWatch } from "react-hook-form"; import { TfiKey } from "react-icons/tfi"; import { primaryRGBA, primary, secondary } from "../../../colors"; import { ModalHeader } from "./ModalHeader"; import { AuthContext } from "../../../App"; import { AuthModalProps } from "./types"; export const AuthenticationModal = ({ open, onClose, isUpdate, }: Omit<AuthModalProps, "type">) => { const { control, register, formState, setError, reset } = useForm<{ password: string; oldPassword: string; newPassword: string; }>({ mode: "onChange", }); const values = useWatch({ control }); const auth = useContext(AuthContext); const onSubmit = useCallback( async ( data: Partial<{ password: string; oldPassword: string; newPassword: string; }> ) => { if (!data.password && !isUpdate) { return setError("password", { message: "Password is required." }); } if (isUpdate && !data.oldPassword) { return setError("oldPassword", { message: "Current password is required.", }); } if (isUpdate && !data.newPassword) { return setError("newPassword", { message: "New password is required.", }); } const res = await fetch( isUpdate ? "/api/updateAdminKey" : "/api/authenticate", { method: "POST", body: JSON.stringify(data), headers: { "Content-Type": "application/json", }, } ); if (!res.ok) { setError(isUpdate ? "newPassword" : "password", { message: await res.text(), }); reset(); } else { auth.setAuthenticated?.(true); reset(); onClose(); } }, [isUpdate, setError, reset, auth, onClose] ); return ( <Modal show={open} onHide={onClose} style={{ backgroundColor: primaryRGBA }} centered > <ModalHeader onClose={onClose} title={isUpdate ? "Set new Admin key" : "Admin Login"} icon={<TfiKey size={50} className='ml-0 mr-auto' />} /> <Modal.Body style={{ border: "2px solid black", borderTop: "none", backgroundColor: primary, }} > <Form className='mb-2' onSubmit={(ev) => { ev.preventDefault(); onSubmit(values); }} > {isUpdate && ( <> <Form.Group as={Row} className='mb-2'> <Col sm='4'> <Form.Label>Current Password</Form.Label> </Col> <Col> <Form.Control {...register("oldPassword", { required: true })} type='password' placeholder='Enter current admin password ...' isInvalid={!!formState.errors.oldPassword} /> <Form.Control.Feedback type='invalid'> {!values.oldPassword ? "Old password is required" : formState.errors.oldPassword?.message} </Form.Control.Feedback> </Col> </Form.Group> <Form.Group as={Row} className='mb-2'> <Col sm='4'> <Form.Label>New Password</Form.Label> </Col> <Col> <Form.Control {...register("newPassword", { required: true, })} type='password' placeholder={`Enter new admin password ...`} isInvalid={!!formState.errors.newPassword} /> <Form.Control.Feedback type='invalid'> {!values.newPassword ? "New password is required" : formState.errors.newPassword?.message} </Form.Control.Feedback> </Col> </Form.Group>{" "} </> )} {!isUpdate && ( <Form.Group as={Row} className='mb-2'> <Col sm='4'> <Form.Label>Password</Form.Label> </Col> <Col> <Form.Control {...register("password", { required: true, })} type='password' placeholder={`Enter admin password ...`} isInvalid={!!formState.errors.password} /> <Form.Control.Feedback type='invalid'> {!values.password ? "Password is required" : formState.errors.password?.message} </Form.Control.Feedback> </Col> </Form.Group> )} <div className='d-flex mx-auto mb-auto mt-2 w-100'> <Button style={{ borderRadius: "5px", backgroundColor: secondary, color: "black", border: "2px solid black", marginLeft: "auto", marginRight: "10px", }} onClick={() => onSubmit(values)} > Send </Button> </div> </Form> </Modal.Body> </Modal> ); };