aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/Books.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/Books.svelte')
-rw-r--r--frontend/src/Books.svelte165
1 files changed, 165 insertions, 0 deletions
diff --git a/frontend/src/Books.svelte b/frontend/src/Books.svelte
new file mode 100644
index 0000000..db1c10b
--- /dev/null
+++ b/frontend/src/Books.svelte
@@ -0,0 +1,165 @@
+<script lang="ts">
+ import { fetchFromServer, deleteOnServer } from "./utils";
+ import Search from "./Search.svelte";
+
+ export let whereami: string;
+ export let ebook: object;
+
+ // let thead: HTMLTableSectionElement, tbody: HTMLTableSectionElement;
+ let searchCom: Search;
+ let filters: any = { key: 2 };
+ let books: Array<any> = [];
+ let _books: Array<any> = [];
+ async function loadData() {
+ _books = await fetchFromServer("/books");
+ books = _books;
+ }
+ loadData();
+
+ let showSearch = false;
+
+ $: {
+ async function getBooks() {
+ if (Object.keys(filters).length === 1) {
+ books = _books;
+ } else {
+ books = _books.filter((b: any) => {
+ for (const fk in filters) {
+ const fv = filters[fk];
+ if (!fv || fk === "key") continue;
+ if (
+ b[fk]
+ .toString()
+ .toLowerCase()
+ .includes(fv.toString().toLowerCase())
+ )
+ return true;
+ }
+ return false;
+ });
+ }
+ }
+ getBooks();
+ }
+
+ function add() {
+ whereami = "add-book";
+ }
+ function search() {
+ showSearch = !showSearch;
+ }
+ function edit(book: object) {
+ whereami = "edit-book";
+ ebook = book;
+ }
+ async function remove(id: number) {
+ await deleteOnServer("/book?bid=" + id, true);
+ _books = _books.filter((b) => b.id !== id);
+ }
+ function clearFilters() {
+ searchCom.clear();
+ filters = { key: Math.random() };
+ }
+</script>
+
+<main>
+ <button type="button" class="main-btn" on:click={add}>Add</button>
+ <button type="button" class="main-btn" on:click={search}>
+ {showSearch ? "Hide" : "Show"} search dialog
+ </button>
+ <button type="button" class="main-btn" on:click={clearFilters}>
+ Clear filters
+ </button>
+ <button type="button" class="main-btn" on:click={loadData}>
+ Reload data
+ </button>
+ {#if showSearch}
+ <Search bind:filters bind:this={searchCom} />
+ {/if}
+ <table>
+ <thead>
+ <tr>
+ <th>Id</th>
+ <th>Author</th>
+ <th>Title</th>
+ <th>Year of<br />publication</th>
+ <th>Publisher</th>
+ <th>Isbn</th>
+ <th>Format</th>
+ <th>Pages</th>
+ <th>Description</th>
+ <th />
+ <th />
+ </tr>
+ </thead>
+ <tbody>
+ {#each books as book}
+ <tr>
+ <td>{book.id}</td>
+ <td>{book.author}</td>
+ <td>{book.title}</td>
+ <td>{book.year}</td>
+ <td>{book.publisher}</td>
+ <td>{book.isbn}</td>
+ <td>{book.format}</td>
+ <td>{book.pages}</td>
+ <td>{book.description}</td>
+ <td>
+ <button
+ type="button"
+ class="action-btn"
+ on:click={() => edit(book)}
+ >
+ Edit
+ </button>
+ </td>
+ <td>
+ <button
+ type="button"
+ class="action-btn"
+ on:click={() => remove(book.id)}
+ >
+ Remove
+ </button>
+ </td>
+ </tr>
+ {/each}
+ </tbody>
+ </table>
+</main>
+
+<style>
+ :root {
+ font-family: "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell;
+ }
+
+ main {
+ text-align: center;
+ }
+ table {
+ margin: 0 auto;
+ border-collapse: collapse;
+ width: 90%;
+ font-size: 1.5em;
+ }
+ thead {
+ font-weight: bold;
+ }
+ td,
+ th {
+ border: 1px solid black;
+ }
+ .main-btn {
+ margin-top: 30px;
+ margin-bottom: 30px;
+ margin-left: 15px;
+ font-size: 1.9em;
+ text-decoration: underline;
+ }
+ .action-btn {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ font-size: 1.2em;
+ text-decoration: underline;
+ }
+</style>