You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.6 KiB
48 lines
1.6 KiB
|
6 years ago
|
import { component, html, useState } from 'haunted';
|
||
|
|
import { useMutation } from '@apollo/react-hooks';
|
||
|
|
import * as yup from 'yup';
|
||
|
|
import { AddBook, GetBooks } from './queries'
|
||
|
|
import Css from './bookform.scss';
|
||
|
|
|
||
|
|
const schema = yup.object().shape({
|
||
|
|
title: yup.string().required(),
|
||
|
|
author: yup.string().required(),
|
||
|
|
});
|
||
|
|
|
||
|
|
const BookForm = () => {
|
||
|
|
const [title, setTitle] = useState("");
|
||
|
|
const [author, setAuthor] = useState("");
|
||
|
|
const [addBook, { loading }] = useMutation(AddBook);
|
||
|
|
|
||
|
|
return html`
|
||
|
|
<style>${Css.toString()}</style>
|
||
|
|
<input type="text"
|
||
|
|
placeholder="book title"
|
||
|
|
.value=${title}
|
||
|
|
@change=${(e: any) => setTitle(e.target.value)}>
|
||
|
|
<input type="text"
|
||
|
|
placeholder="author name"
|
||
|
|
.value=${author}
|
||
|
|
@change=${(e: any) => setAuthor(e.target.value)}>
|
||
|
|
<button @click=${async () => {
|
||
|
|
try {
|
||
|
|
const data = await schema.validate({ author, title });
|
||
|
|
await addBook({ variables: data, update: (cache, result) => {
|
||
|
|
const list: any = cache.readQuery({ query: GetBooks });
|
||
|
|
cache.writeQuery({ query: GetBooks, data: { books: [...list.books, result.data.addBook] }});
|
||
|
|
}});
|
||
|
|
setTitle("");
|
||
|
|
setAuthor("");
|
||
|
|
} catch(e) {
|
||
|
|
console.log(e);
|
||
|
|
if (e instanceof yup.ValidationError) {
|
||
|
|
console.log("validation error");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}} ?disabled=${loading}>Add book</button>
|
||
|
|
`;
|
||
|
|
}
|
||
|
|
|
||
|
|
customElements.define('book-form', component(BookForm));
|
||
|
|
|