n39librarian/frontend/src/shared/components/modals/MoveShelfModal.tsx

140 lines
4.2 KiB
TypeScript

import { useMutation, useQuery } from "@tanstack/react-query";
import { Button, Col, Form, Modal, Row } from "react-bootstrap";
import { ImBook, ImCancelCircle } from "react-icons/im";
import { ModalHeader } from "./ModalHeader";
import { MoveShelfAction, MoveShelfModalProps } from "./types";
import { useForm, useWatch } from "react-hook-form";
import { useState } from "react";
export const MoveShelfModal = ({
books,
open,
onClose,
}: Omit<MoveShelfModalProps, "type">): React.JSX.Element => {
const { control, register, formState, setError } = useForm<MoveShelfAction>({
mode: "onChange",
});
const values = useWatch({ control });
const { mutate: mv } = useMutation({
mutationFn: async () => {
if (!values.target) {
setError("target", { message: "Target shelf is required" });
return;
}
await fetch(`/api/shelf/move`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ ...values, books }),
});
onClose();
},
});
const { data: shelves, isLoading } = useQuery<string[]>({
queryFn: async () => {
const response = await fetch(`/api/shelves/list`);
const data = await response.text();
return data
.split(",")
.map((s) => s.replaceAll('"', "").replace("[", "").replace("]", ""));
},
queryKey: ["shleves"],
});
const [addNew, setAddNew] = useState<boolean>(false);
return (
<Modal show={open} onHide={onClose} centered>
<ModalHeader
onClose={onClose}
title={"Move to Shelf"}
icon={<ImBook size={50} className='ml-0 mr-auto' />}
/>
<Modal.Body
style={{
borderTop: "none",
}}
>
<Form.Group as={Row} className='mb-2'>
<Col className='d-flex' sm='2'>
<Form.Label className='m-auto'>Shelf</Form.Label>
</Col>
<Col>
{!isLoading &&
(addNew ? (
<div className='d-flex'>
<Form.Control
id='move-shelf-text-input'
{...register("target", { required: true })}
/>
<Button
style={{
background: "transparent",
marginLeft: "0px",
marginRight: "10px",
}}
className='d-flex m-auto'
onClick={() => setAddNew(false)}
>
<ImCancelCircle className='m-auto primary' size={20} />
</Button>
</div>
) : (
<Form.Select
id='move-shelf-select'
{...register("target", {
required: true,
onChange: (ev) => {
if (ev.target.value === "addNew") {
setAddNew(true);
}
},
})}
isInvalid={!!formState.errors.target}
>
{shelves?.map((shelf) => (
<option key='key' value={shelf}>
{shelf}
</option>
))}
<option value='addNew'>Add new</option>
</Form.Select>
))}
<Form.Control.Feedback type='invalid'>
{!values.target
? "Target shelf is required"
: formState.errors.target?.message}
</Form.Control.Feedback>
</Col>
</Form.Group>
<div className='d-flex mx-auto mb-auto mt-2 w-100'>
<Button
style={{
borderRadius: "5px",
marginLeft: "auto",
marginRight: "10px",
}}
onClick={() => onClose()}
>
Cancel
</Button>
<Button
style={{
borderRadius: "5px",
marginLeft: "0px",
marginRight: "10px",
}}
onClick={() => mv()}
>
Move
</Button>
</div>
</Modal.Body>
</Modal>
);
};