Added page and endpoints for managing Tags
This commit is contained in:
6
yaba-web/src/components/external/index.js
vendored
6
yaba-web/src/components/external/index.js
vendored
@ -5,6 +5,9 @@ import Row from "react-bootstrap/Row";
|
||||
import Form from 'react-bootstrap/Form';
|
||||
import Button from "react-bootstrap/Button";
|
||||
import Modal from 'react-bootstrap/Modal'
|
||||
import { Table } from "react-bootstrap";
|
||||
import Dropdown from 'react-bootstrap/Dropdown';
|
||||
import DropdownButton from 'react-bootstrap/DropdownButton';
|
||||
|
||||
export {
|
||||
Alert,
|
||||
@ -14,4 +17,7 @@ export {
|
||||
Form,
|
||||
Button,
|
||||
Modal,
|
||||
Table,
|
||||
Dropdown,
|
||||
DropdownButton,
|
||||
};
|
||||
@ -57,6 +57,7 @@ export function Header(props) {
|
||||
<NavDropdown.Divider />
|
||||
<NavDropdown.Item href="/bookmarks/new">New</NavDropdown.Item>
|
||||
</NavDropdown>
|
||||
<Nav.Link href="/tags">Tags</Nav.Link>
|
||||
<Nav.Link onClick={handleLogout}>Logout</Nav.Link>
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -5,6 +5,8 @@ import { Auth0ProviderWithNavigate } from "./auth0ProviderWithNavigate";
|
||||
import { ProtectedRoute } from "./protectedRoute";
|
||||
import { SplashScreen } from "./shared/splashScreen";
|
||||
import { SearchForm } from "./shared/searchForm";
|
||||
import { UpsertTagModal } from "./tags/upsertTagModal";
|
||||
import { InterceptModal } from "./shared/interceptModal";
|
||||
|
||||
export {
|
||||
Footer,
|
||||
@ -13,5 +15,7 @@ export {
|
||||
Auth0ProviderWithNavigate,
|
||||
ProtectedRoute,
|
||||
SplashScreen,
|
||||
SearchForm
|
||||
SearchForm,
|
||||
UpsertTagModal,
|
||||
InterceptModal,
|
||||
};
|
||||
32
yaba-web/src/components/shared/interceptModal.jsx
Normal file
32
yaba-web/src/components/shared/interceptModal.jsx
Normal file
@ -0,0 +1,32 @@
|
||||
import React from "react";
|
||||
import { Button, Form, Modal } from "../external";
|
||||
|
||||
export function InterceptModal(props) {
|
||||
return (
|
||||
<Modal
|
||||
show={props.show}
|
||||
onHide={props.onHide}
|
||||
keyboard={false}
|
||||
backdrop={props.backdrop}
|
||||
>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>{props.title}</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>{props.message}</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button
|
||||
variant={props.secondaryAction.variant}
|
||||
onClick={props.secondaryAction.onClick}
|
||||
>
|
||||
{props.secondaryAction.text}
|
||||
</Button>
|
||||
<Button
|
||||
variant={props.primaryAction.variant}
|
||||
onClick={props.primaryAction.onClick}
|
||||
>
|
||||
{props.primaryAction.text}
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
73
yaba-web/src/components/tags/upsertTagModal.jsx
Normal file
73
yaba-web/src/components/tags/upsertTagModal.jsx
Normal file
@ -0,0 +1,73 @@
|
||||
import React from "react";
|
||||
import { Button, Form, Modal } from "../external";
|
||||
import { useFormik } from "formik";
|
||||
import * as Yup from "yup"
|
||||
|
||||
export function UpsertTagModal(props) {
|
||||
const formik = useFormik({
|
||||
initialValues: props.tag,
|
||||
validationSchema: Yup.object({
|
||||
name: Yup.string().required("Name is required").lowercase()
|
||||
}),
|
||||
enableReinitialize: true,
|
||||
onSubmit: async(values) => props.onSave(values)
|
||||
});
|
||||
|
||||
return (
|
||||
<Modal
|
||||
show={props.show}
|
||||
onHide={props.onHide}
|
||||
keyboard={false}
|
||||
backdrop="static"
|
||||
>
|
||||
<Form onSubmit={formik.handleSubmit}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>{props.tag.id > 0 ? "Edit Tag" : "New Tag"}</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<Form.Group className="mb-3">
|
||||
<Form.Label>Name:</Form.Label>
|
||||
<Form.Control
|
||||
id="name"
|
||||
type="text"
|
||||
placeholder="Enter tag name"
|
||||
defaultValue={formik.values.name}
|
||||
onBlur={formik.handleChange}
|
||||
isInvalid={!!formik.errors.name}
|
||||
/>
|
||||
<Form.Control.Feedback
|
||||
type="invalid"
|
||||
className="d-flex justify-content-start"
|
||||
>
|
||||
{formik.errors.name}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group>
|
||||
<Form.Check
|
||||
id="isHidden"
|
||||
type="switch"
|
||||
label="Mark as hidden"
|
||||
checked={formik.values.isHidden}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
</Form.Group>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
{ props.tag.id > 0 && <Button
|
||||
variant="danger"
|
||||
onClick={props.onDelete}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
}
|
||||
<Button
|
||||
variant="primary"
|
||||
type="submit"
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user