184 lines
5.4 KiB
TypeScript
184 lines
5.4 KiB
TypeScript
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>
|
|
);
|
|
};
|