From 58e1ffa9effc92f5ddebee4068d5931be12201b0 Mon Sep 17 00:00:00 2001
From: Maksymilian Jopek <maks@jopek.eu>
Date: Thu, 10 Mar 2022 15:39:25 +0100
Subject: Initial commit w/ v1.0.0

---
 frontend/src/Books.svelte | 165 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 165 insertions(+)
 create mode 100644 frontend/src/Books.svelte

(limited to 'frontend/src/Books.svelte')

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>
-- 
cgit v1.3.1

