generated from schreifuchs/wails-template
management of library
This commit is contained in:
@ -1,25 +1,37 @@
|
||||
<script lang="ts">
|
||||
import "./app.css";
|
||||
import { Router, Route, Link, navigate } from "svelte-routing";
|
||||
import Home from "./routes/Home.svelte";
|
||||
import "./app.css";
|
||||
import { Navbar, DarkMode, Heading } from "flowbite-svelte";
|
||||
import { HomeOutline } from "flowbite-svelte-icons";
|
||||
import Books from "./routes/Books.svelte";
|
||||
import Clients from "./routes/Clients.svelte";
|
||||
import Lendings from "./routes/Lendings.svelte";
|
||||
let url: string = $state("/");
|
||||
</script>
|
||||
|
||||
<main class="flex-col h-screen items-center bg-gray-50 dark:bg-gray-900">
|
||||
<Router bind:url>
|
||||
<Navbar class="border-b">
|
||||
<button
|
||||
class="grid grid-cols-3 items-center"
|
||||
onclick={() => navigate("/")}
|
||||
>
|
||||
<HomeOutline />
|
||||
<span class="col-span-2">HOME</span>
|
||||
</button>
|
||||
<div class="flex gap-5">
|
||||
<button
|
||||
class="grid grid-cols-3 items-center"
|
||||
onclick={() => navigate("/")}
|
||||
>
|
||||
<HomeOutline />
|
||||
<span class="col-span-2">HOME</span>
|
||||
</button>
|
||||
<Link to="/clients">Clients</Link>
|
||||
<Link to="/books">Books</Link>
|
||||
</div>
|
||||
<DarkMode />
|
||||
</Navbar>
|
||||
<Route path="/"><Home /></Route>
|
||||
<Route path="/"><Lendings clientId={null} /></Route>
|
||||
<Route path="/books"><Books /></Route>
|
||||
<Route path="/clients"><Clients /></Route>
|
||||
|
||||
<Route path="/clients/:id" let:params>
|
||||
<Lendings clientId={parseInt(params.id)} />
|
||||
</Route>
|
||||
</Router>
|
||||
</main>
|
||||
|
24
frontend/src/components/AuthorEditor.svelte
Normal file
24
frontend/src/components/AuthorEditor.svelte
Normal file
@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { Button, Input, Label } from "flowbite-svelte";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
|
||||
let {
|
||||
author = new model.Author(),
|
||||
onsubmit,
|
||||
}: { author: model.Author; onsubmit: (a: model.Author) => void } = $props();
|
||||
|
||||
function submit(e: Event) {
|
||||
e.preventDefault();
|
||||
onsubmit(author);
|
||||
}
|
||||
</script>
|
||||
|
||||
<form onsubmit={submit}>
|
||||
<div class="m-5">
|
||||
<Label>Name</Label>
|
||||
<Input type="text" bind:value={author.Name} />
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Button type="submit">Save</Button>
|
||||
</div>
|
||||
</form>
|
73
frontend/src/components/BookEditor.svelte
Normal file
73
frontend/src/components/BookEditor.svelte
Normal file
@ -0,0 +1,73 @@
|
||||
<script lang="ts">
|
||||
import { Button, Input, Label, Modal, Select } from "flowbite-svelte";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import { GetAuthors, SaveAuthor } from "../../wailsjs/go/main/App";
|
||||
import AuthorEditor from "./AuthorEditor.svelte";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
const ISBNRegex =
|
||||
"^(?:ISBN(?:-13)?:? )?(?=[0-9]{13}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)97[89][- ]?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9]$";
|
||||
|
||||
let {
|
||||
book = $bindable(),
|
||||
onsubmit = (_) => {},
|
||||
}: { book: model.Book; onsubmit: (a: model.Book) => void } = $props();
|
||||
|
||||
let authors: model.Author[] = $state([]);
|
||||
|
||||
let modal: boolean = $state(false);
|
||||
let newAuthor: model.Author = $state();
|
||||
|
||||
function update() {
|
||||
GetAuthors().then((as) => (authors = as));
|
||||
}
|
||||
|
||||
function submit(e: Event) {
|
||||
e.preventDefault();
|
||||
onsubmit(book);
|
||||
}
|
||||
onMount(update);
|
||||
</script>
|
||||
|
||||
<Modal bind:open={modal}>
|
||||
<AuthorEditor
|
||||
author={newAuthor}
|
||||
onsubmit={(a) => {
|
||||
SaveAuthor(a).then(update);
|
||||
modal = false;
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<form onsubmit={submit}>
|
||||
<div class="m-5">
|
||||
<Label>Name</Label>
|
||||
<Input type="text" bind:value={book.Title} />
|
||||
</div>
|
||||
|
||||
<div class="m-5">
|
||||
<Label>ISBN</Label>
|
||||
<Input pattern={ISBNRegex} type="text" bind:value={book.ISBN} />
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Label>Author</Label>
|
||||
<div class="grid grid-cols-5 gap-5">
|
||||
<Select
|
||||
class="col-span-4"
|
||||
items={authors.map((a) => {
|
||||
return { value: a.ID, name: a.Name };
|
||||
})}
|
||||
bind:value={book.AuthorID}
|
||||
/>
|
||||
<Button
|
||||
onclick={() => {
|
||||
newAuthor = new model.Author();
|
||||
modal = true;
|
||||
}}>New</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Button type="submit">Save</Button>
|
||||
</div>
|
||||
</form>
|
30
frontend/src/components/ClientEditor.svelte
Normal file
30
frontend/src/components/ClientEditor.svelte
Normal file
@ -0,0 +1,30 @@
|
||||
<script lang="ts">
|
||||
import { Button, Input, Label } from "flowbite-svelte";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
|
||||
let {
|
||||
client = $bindable(),
|
||||
onsubmit = (_) => {},
|
||||
}: { client: model.Client; onsubmit: (a: model.Client) => void } = $props();
|
||||
|
||||
function submit(e: Event) {
|
||||
e.preventDefault();
|
||||
onsubmit(client);
|
||||
}
|
||||
</script>
|
||||
|
||||
<form onsubmit={submit}>
|
||||
<div class="m-5">
|
||||
<Label>Name</Label>
|
||||
<Input type="text" bind:value={client.Name} />
|
||||
</div>
|
||||
|
||||
<div class="m-5">
|
||||
<Label>ISBN</Label>
|
||||
<Input type="email" bind:value={client.Email} />
|
||||
</div>
|
||||
|
||||
<div class="m-5">
|
||||
<Button type="submit">Save</Button>
|
||||
</div>
|
||||
</form>
|
73
frontend/src/components/LendingEditor.svelte
Normal file
73
frontend/src/components/LendingEditor.svelte
Normal file
@ -0,0 +1,73 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Input,
|
||||
Label,
|
||||
Modal,
|
||||
Select,
|
||||
} from "flowbite-svelte";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import {
|
||||
GetAuthors,
|
||||
GetAvailableBooks,
|
||||
GetClients,
|
||||
SaveAuthor,
|
||||
} from "../../wailsjs/go/main/App";
|
||||
import AuthorEditor from "./AuthorEditor.svelte";
|
||||
import { onMount } from "svelte";
|
||||
import TimeInput from "./TimeInput.svelte";
|
||||
|
||||
let {
|
||||
lending = $bindable(),
|
||||
onsubmit = (_) => {},
|
||||
}: { lending: model.Lending; onsubmit: (l: model.Lending) => void } =
|
||||
$props();
|
||||
|
||||
let books: model.Book[] = $state([]);
|
||||
let clients: model.Client[] = $state([]);
|
||||
|
||||
function update() {
|
||||
GetAvailableBooks().then((bs) => (books = bs));
|
||||
GetClients().then((cl) => (clients = cl));
|
||||
}
|
||||
|
||||
function submit(e: Event) {
|
||||
e.preventDefault();
|
||||
onsubmit(lending);
|
||||
}
|
||||
onMount(update);
|
||||
</script>
|
||||
|
||||
<form onsubmit={submit}>
|
||||
<div class="m-5">
|
||||
<Label>Book</Label>
|
||||
<Select
|
||||
class="col-span-4"
|
||||
items={books.map((b) => {
|
||||
return { value: b.ID, name: b.Title };
|
||||
})}
|
||||
bind:value={lending.BookID}
|
||||
/>
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Label>Client</Label>
|
||||
<Select
|
||||
class="col-span-4"
|
||||
items={clients.map((c) => {
|
||||
return { value: c.ID, name: `${c.Email} ~ ${c.Name}` };
|
||||
})}
|
||||
bind:value={lending.ClientID}
|
||||
/>
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Label>Due Date</Label>
|
||||
<TimeInput bind:value={lending.DueDate} />
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Checkbox bind:checked={lending.Returned}>Returned</Checkbox>
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Button type="submit">Save</Button>
|
||||
</div>
|
||||
</form>
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Input } from "flowbite-svelte";
|
||||
|
||||
let { value }: { value: Date } = $props();
|
||||
let { value = $bindable() }: { value: Date } = $props();
|
||||
|
||||
const formatDateTimeLocal = (date: Date) => {
|
||||
const pad = (num) => num.toString().padStart(2, "0");
|
||||
|
24
frontend/src/routes/AuthorEditor.svelte
Normal file
24
frontend/src/routes/AuthorEditor.svelte
Normal file
@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { Button, Input, Label } from "flowbite-svelte";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
|
||||
let {
|
||||
author = $bindable(),
|
||||
onsubmit = (_) => {},
|
||||
}: { author: model.Author; onsubmit: (a: model.Author) => void } = $props();
|
||||
|
||||
function submit(e: Event) {
|
||||
e.preventDefault();
|
||||
onsubmit(author);
|
||||
}
|
||||
</script>
|
||||
|
||||
<form onsubmit={submit}>
|
||||
<div class="m-5">
|
||||
<Label>Name</Label>
|
||||
<Input type="text" bind:value={author.Name} />
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Button type="submit">Save</Button>
|
||||
</div>
|
||||
</form>
|
118
frontend/src/routes/Books.svelte
Normal file
118
frontend/src/routes/Books.svelte
Normal file
@ -0,0 +1,118 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Modal,
|
||||
Spinner,
|
||||
Table,
|
||||
TableBody,
|
||||
TableBodyCell,
|
||||
TableBodyRow,
|
||||
TableHead,
|
||||
TableHeadCell,
|
||||
} from "flowbite-svelte";
|
||||
import BookEditor from "../components/BookEditor.svelte";
|
||||
import { onMount } from "svelte";
|
||||
import {
|
||||
GetBooks,
|
||||
SaveBook,
|
||||
BookLended,
|
||||
SaveLending,
|
||||
} from "../../wailsjs/go/main/App";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import LendingEditor from "../components/LendingEditor.svelte";
|
||||
|
||||
let books: model.Book[] = $state();
|
||||
|
||||
let book: model.Book | null = $state(null);
|
||||
let lending: model.Lending | null = $state(null);
|
||||
let modal: boolean = $state(false);
|
||||
|
||||
function update() {
|
||||
GetBooks().then((bs) => (books = bs));
|
||||
}
|
||||
onMount(update);
|
||||
</script>
|
||||
|
||||
{#if book}
|
||||
<Modal bind:open={modal} title="Book">
|
||||
<BookEditor
|
||||
bind:book
|
||||
onsubmit={(b) => {
|
||||
SaveBook(b).then(update);
|
||||
modal = false;
|
||||
book = null;
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
{:else if lending}
|
||||
<Modal bind:open={modal} title="New Lending">
|
||||
<LendingEditor
|
||||
bind:lending
|
||||
onsubmit={(l) => {
|
||||
SaveLending(l).then(update);
|
||||
modal = false;
|
||||
lending = null;
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
{/if}
|
||||
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableHeadCell>Title</TableHeadCell>
|
||||
<TableHeadCell>Author</TableHeadCell>
|
||||
<TableHeadCell>ISBN</TableHeadCell>
|
||||
<TableHeadCell>Status</TableHeadCell>
|
||||
|
||||
<TableHeadCell>
|
||||
<Button
|
||||
onclick={() => {
|
||||
book = new model.Book();
|
||||
modal = true;
|
||||
}}>New</Button
|
||||
></TableHeadCell
|
||||
>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{#each books as b}
|
||||
<TableBodyRow>
|
||||
<TableBodyCell>{b.Title}</TableBodyCell>
|
||||
<TableBodyCell>{b.Author.Name}</TableBodyCell>
|
||||
<TableBodyCell>{b.ISBN}</TableBodyCell>
|
||||
<TableBodyCell
|
||||
>{#await BookLended(b.ID)}
|
||||
<Spinner />
|
||||
{:then lended}
|
||||
{#if lended}
|
||||
<Badge color="red">Lended</Badge>
|
||||
{:else}
|
||||
<Badge class="text-sm" color="green">Available</Badge>
|
||||
{/if}
|
||||
{/await}</TableBodyCell
|
||||
>
|
||||
|
||||
<TableBodyCell>
|
||||
{#await BookLended(b.ID) then lended}
|
||||
{#if !lended}
|
||||
<Button
|
||||
onclick={() => {
|
||||
lending = new model.Lending();
|
||||
lending.BookID = b.ID;
|
||||
lending.DueDate = new Date();
|
||||
modal = true;
|
||||
}}>Lend</Button
|
||||
>
|
||||
{/if}
|
||||
{/await}
|
||||
<Button
|
||||
onclick={() => {
|
||||
book = b;
|
||||
modal = true;
|
||||
}}>Edit</Button
|
||||
>
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</Table>
|
107
frontend/src/routes/Clients.svelte
Normal file
107
frontend/src/routes/Clients.svelte
Normal file
@ -0,0 +1,107 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
Table,
|
||||
TableBody,
|
||||
TableBodyCell,
|
||||
TableBodyRow,
|
||||
TableHead,
|
||||
TableHeadCell,
|
||||
} from "flowbite-svelte";
|
||||
import ClientEditor from "../components/ClientEditor.svelte";
|
||||
import { onMount } from "svelte";
|
||||
import {
|
||||
GetClients,
|
||||
SaveClient,
|
||||
SaveLending,
|
||||
} from "../../wailsjs/go/main/App";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import LendingEditor from "../components/LendingEditor.svelte";
|
||||
import { navigate } from "svelte-routing";
|
||||
|
||||
let clients: model.Client[] = $state();
|
||||
|
||||
let client: model.Client | null = $state(null);
|
||||
let lending: model.Lending | null = $state(null);
|
||||
let modal: boolean = $state(false);
|
||||
|
||||
function update() {
|
||||
GetClients().then((cs) => (clients = cs));
|
||||
}
|
||||
onMount(update);
|
||||
</script>
|
||||
|
||||
{#if client}
|
||||
<Modal bind:open={modal} title="Client">
|
||||
<ClientEditor
|
||||
{client}
|
||||
onsubmit={(c) => {
|
||||
SaveClient(c).then(update);
|
||||
modal = false;
|
||||
}}
|
||||
/>
|
||||
</Modal>{:else if lending}
|
||||
<Modal bind:open={modal} title="New Lending">
|
||||
<LendingEditor
|
||||
bind:lending
|
||||
onsubmit={(l) => {
|
||||
SaveLending(l).then(update);
|
||||
modal = false;
|
||||
lending = null;
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
{/if}
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableHeadCell>Name</TableHeadCell>
|
||||
<TableHeadCell>Email</TableHeadCell>
|
||||
<TableHeadCell>Active Lendings</TableHeadCell>
|
||||
<TableHeadCell>Overdue Lendings</TableHeadCell>
|
||||
<TableHeadCell>
|
||||
<Button
|
||||
onclick={() => {
|
||||
client = new model.Client();
|
||||
modal = true;
|
||||
}}>New</Button
|
||||
></TableHeadCell
|
||||
>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{#each clients as c}
|
||||
<TableBodyRow>
|
||||
<TableBodyCell>{c.Name}</TableBodyCell>
|
||||
<TableBodyCell>{c.Email}</TableBodyCell>
|
||||
<TableBodyCell
|
||||
>{c.Lendings.filter((l) => {
|
||||
return !l.Returned;
|
||||
}).length}
|
||||
</TableBodyCell>
|
||||
|
||||
<TableBodyCell
|
||||
>{c.Lendings.filter((l) => {
|
||||
return new Date(l.DueDate).getTime() > Date.now();
|
||||
}).length}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
<Button onclick={() => navigate(`/clients/${c.ID}`)}>View</Button>
|
||||
<Button
|
||||
onclick={() => {
|
||||
lending = new model.Lending();
|
||||
lending.DueDate = new Date();
|
||||
lending.ClientID = c.ID;
|
||||
modal = true;
|
||||
}}>Lend a Book</Button
|
||||
>
|
||||
<Button
|
||||
onclick={() => {
|
||||
client = c;
|
||||
modal = true;
|
||||
}}>Edit</Button
|
||||
>
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</Table>
|
@ -1,74 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import {
|
||||
GetThings,
|
||||
DeleteThing,
|
||||
NewThing,
|
||||
} from "../../wailsjs/go/things/Service";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import {
|
||||
Label,
|
||||
Input,
|
||||
Button,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeadCell,
|
||||
TableBody,
|
||||
TableBodyRow,
|
||||
TableBodyCell,
|
||||
} from "flowbite-svelte";
|
||||
|
||||
let name: string = $state();
|
||||
let thingsList: model.Thing[] = $state([]);
|
||||
|
||||
function update() {
|
||||
GetThings().then((ts) => {
|
||||
thingsList = ts;
|
||||
});
|
||||
}
|
||||
|
||||
function submit(e: Event) {
|
||||
e.preventDefault();
|
||||
NewThing(name).then(update);
|
||||
name = "";
|
||||
}
|
||||
|
||||
function deleteEvent(id: number) {
|
||||
DeleteThing(id).then(update);
|
||||
}
|
||||
|
||||
onMount(update);
|
||||
</script>
|
||||
|
||||
<form class="max-w-96 m-5 grid-cols-1 gap-10" onsubmit={submit}>
|
||||
<div class="m-5">
|
||||
<Label for="first_name" class="mb-2">First name</Label>
|
||||
<Input type="text" placeholder="John" bind:value={name} required />
|
||||
</div>
|
||||
<div class="m-5">
|
||||
<Button type="submit">Submit</Button>
|
||||
</div>
|
||||
</form>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableHeadCell>ID</TableHeadCell>
|
||||
<TableHeadCell>Name</TableHeadCell>
|
||||
<TableHeadCell>Delete</TableHeadCell>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{#each thingsList as t}
|
||||
<TableBodyRow>
|
||||
<TableBodyCell>
|
||||
{t.ID}
|
||||
</TableBodyCell>
|
||||
|
||||
<TableBodyCell>
|
||||
{t.Name}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
<Button on:click={(_) => deleteEvent(t.ID)}>Delete</Button>
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</Table>
|
188
frontend/src/routes/Lendings.svelte
Normal file
188
frontend/src/routes/Lendings.svelte
Normal file
@ -0,0 +1,188 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
GetReturnedLendings,
|
||||
GetLendings,
|
||||
ReturnLending,
|
||||
SaveLending,
|
||||
DeleteLending,
|
||||
} from "../../wailsjs/go/main/App";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import { BrowserOpenURL } from "../../wailsjs/runtime/runtime";
|
||||
import { onMount } from "svelte";
|
||||
import {
|
||||
Button,
|
||||
Heading,
|
||||
Modal,
|
||||
P,
|
||||
Timeline,
|
||||
TimelineItem,
|
||||
} from "flowbite-svelte";
|
||||
import LendingEditor from "../components/LendingEditor.svelte";
|
||||
|
||||
let { clientId = null }: { clientId: number | null } = $props();
|
||||
|
||||
let lendings: model.Lending[] = $state([]);
|
||||
let returnedLendings: model.Lending[] = $state([]);
|
||||
|
||||
let lending: model.Lending = $state();
|
||||
let modal: boolean = $state(false);
|
||||
|
||||
function update() {
|
||||
GetLendings().then((ls) => {
|
||||
lendings = ls.filter((l) => {
|
||||
if (clientId && l.ClientID !== clientId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
GetReturnedLendings().then((ls) => (returnedLendings = ls.filter((l) => {
|
||||
if (clientId && l.ClientID !== clientId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})));
|
||||
}
|
||||
onMount(update);
|
||||
//
|
||||
</script>
|
||||
|
||||
<Modal bind:open={modal} title="Lending">
|
||||
<LendingEditor
|
||||
bind:lending
|
||||
onsubmit={(l) => {
|
||||
SaveLending(l).then(update);
|
||||
modal = false;
|
||||
lending = null;
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<div class="m-5 grid grid-cols-5">
|
||||
<Heading tag="h1" class="col-span-4">Lendings</Heading>
|
||||
<Button
|
||||
onclick={() => {
|
||||
lending = new model.Lending();
|
||||
lending.DueDate = new Date();
|
||||
if (clientId) {
|
||||
lending.ClientID = clientId
|
||||
}
|
||||
modal = true;
|
||||
}}>New</Button
|
||||
>
|
||||
</div>
|
||||
|
||||
<section class="m-5 mb-20">
|
||||
<Heading tag="h2" class="mb-5">Overdue</Heading>
|
||||
{#if lendings.filter((l) => {
|
||||
return new Date(l.DueDate).getTime() < Date.now();
|
||||
}).length == 0}
|
||||
<P>No Entries</P>
|
||||
{/if}
|
||||
<Timeline>
|
||||
{#each lendings.filter((l) => {
|
||||
return new Date(l.DueDate).getTime() < Date.now();
|
||||
}) as l}
|
||||
<TimelineItem
|
||||
title={`"${l.Book.Title}" is lended to ${l.Client.Name}`}
|
||||
date={new Date(l.DueDate).toLocaleString()}
|
||||
>
|
||||
<P>
|
||||
The book "{l.Book.Title}" (ISBN: {l.Book.ISBN}) is lended to {l.Client
|
||||
.Name} (<button
|
||||
class="underline"
|
||||
onclick={() => BrowserOpenURL(`mailto:${l.Client.Email}`)}
|
||||
>{l.Client.Email}</button
|
||||
>)
|
||||
</P>
|
||||
<div class="flex gap-5 my-5">
|
||||
<Button
|
||||
onclick={() => {
|
||||
lending = l;
|
||||
modal = true;
|
||||
}}>Edit</Button
|
||||
>
|
||||
<Button
|
||||
color="red"
|
||||
onclick={() => {
|
||||
ReturnLending(l).then(update);
|
||||
}}>Set to Returned</Button
|
||||
>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
{/each}
|
||||
</Timeline>
|
||||
</section>
|
||||
<section class="m-5 mb-20">
|
||||
<Heading tag="h2" class="mb-5">Active</Heading>
|
||||
{#if lendings.filter((l) => {
|
||||
return new Date(l.DueDate).getTime() > Date.now();
|
||||
}).length == 0}
|
||||
<P>No Entries</P>
|
||||
{/if}
|
||||
|
||||
<Timeline>
|
||||
{#each lendings.filter((l) => {
|
||||
return new Date(l.DueDate).getTime() > Date.now();
|
||||
}) as l}
|
||||
<TimelineItem
|
||||
title={`"${l.Book.Title}" is lended to ${l.Client.Name}`}
|
||||
date={new Date(l.DueDate).toLocaleString()}
|
||||
>
|
||||
<P>
|
||||
The book "{l.Book.Title}" (ISBN: {l.Book.ISBN}) is lended to {l.Client
|
||||
.Name} (<button
|
||||
class="underline"
|
||||
onclick={() => BrowserOpenURL(`mailto:${l.Client.Email}`)}
|
||||
>{l.Client.Email}</button
|
||||
>)
|
||||
</P>
|
||||
<div class="flex gap-5 my-5">
|
||||
<Button
|
||||
onclick={() => {
|
||||
lending = l;
|
||||
modal = true;
|
||||
}}>Edit</Button
|
||||
>
|
||||
<Button
|
||||
color="red"
|
||||
onclick={() => {
|
||||
ReturnLending(l).then(update);
|
||||
}}>Set to Returned</Button
|
||||
>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
{/each}
|
||||
</Timeline>
|
||||
</section>
|
||||
<section class="m-5 mb-20">
|
||||
<Heading tag="h2" class="mb-5">Returned</Heading>
|
||||
{#if returnedLendings.length == 0}
|
||||
<P>No Entries</P>
|
||||
{/if}
|
||||
<Timeline>
|
||||
{#each returnedLendings as l}
|
||||
<TimelineItem
|
||||
title={`"${l.Book.Title}" was lended to ${l.Client.Name}`}
|
||||
date={new Date(l.DueDate).toLocaleString()}
|
||||
>
|
||||
<P>
|
||||
The book "{l.Book.Title}" (ISBN: {l.Book.ISBN}) was lended to {l
|
||||
.Client.Name} (<button
|
||||
class="underline"
|
||||
onclick={() => BrowserOpenURL(`mailto:${l.Client.Email}`)}
|
||||
>{l.Client.Email}</button
|
||||
>)
|
||||
</P>
|
||||
<div class="flex gap-5 my-5">
|
||||
<Button
|
||||
color="red"
|
||||
onclick={() => {
|
||||
DeleteLending(l).then(update);
|
||||
}}>Delete</Button
|
||||
>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
{/each}
|
||||
</Timeline>
|
||||
</section>
|
Reference in New Issue
Block a user