aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoris2023-09-09 13:50:17 +0200
committerJoris2023-09-09 13:50:17 +0200
commit82429caf3c2886c2d94e09d020e645b06bd4680d (patch)
tree3183bf0c687c25e17fd36a23ced58fd1e6e29dda /src
parent08a5f3519f29cd486d7fe4c295e5d5c7f031104a (diff)
Allow to open book detail in modal
Diffstat (limited to 'src')
-rw-r--r--src/book.ts2
-rw-r--r--src/main.ts10
-rw-r--r--src/view/books.ts61
-rw-r--r--src/view/components/modal.ts26
4 files changed, 91 insertions, 8 deletions
diff --git a/src/book.ts b/src/book.ts
index a5ddb75..328f8e1 100644
--- a/src/book.ts
+++ b/src/book.ts
@@ -1,6 +1,6 @@
export interface Book {
title: string
- subtitle: string
+ subtitle?: string
authors: Array<string>
authorsSort: string
genres: Array<string>
diff --git a/src/main.ts b/src/main.ts
index 21bf215..5885871 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,8 +1,9 @@
-import { h, withVar, mount } from 'lib/rx'
+import { h, withVar, mount, Html } from 'lib/rx'
import * as Search from 'lib/search'
import * as Functions from 'lib/functions'
import * as I18n from 'lib/i18n'
import * as Filters from 'view/filters'
+import * as Books from 'view/books'
import * as Book from 'book'
// @ts-ignore
@@ -34,12 +35,7 @@ mount(withVar<Filters.Model>({}, (filters, updateFilters) =>
),
filteredBooks.map(fb => I18n.unit(fb.length, 'livre', 'livres'))
),
- h('div',
- { className: 'g-Books' },
- filteredBooks.map(fb =>
- fb.map(book => h('img', { className: 'g-Book', src: book.cover }))
- )
- )
+ Books.view(filteredBooks)
)
]
})
diff --git a/src/view/books.ts b/src/view/books.ts
new file mode 100644
index 0000000..6ea0c12
--- /dev/null
+++ b/src/view/books.ts
@@ -0,0 +1,61 @@
+import { h, withVar, mount, Html, Rx } from 'lib/rx'
+import * as Book from 'book'
+import * as Modal from 'view/components/modal'
+
+export function view(books: Rx<Array<Book.Book>>): Html {
+ return h('div',
+ { className: 'g-Books' },
+ withVar<Book.Book | undefined>(undefined, (focusBook, updateFocusBook) => [
+ focusBook.map(book => book && bookDetailModal({
+ book,
+ onClose: () => updateFocusBook(_ => undefined)
+ })),
+ books.map(bs => bs.map(book => viewBook({
+ book,
+ onSelect: (book) => updateFocusBook(_ => book)
+ })))
+ ])
+ )
+}
+
+interface ViewBookParams {
+ book: Book.Book
+ onSelect: (book: Book.Book) => void
+}
+
+function viewBook({ book, onSelect }: ViewBookParams): Html {
+ return h('button',
+ { className: 'g-Book' },
+ h('img',
+ { src: book.cover,
+ className: 'g-Book__Image',
+ onclick: () => onSelect(book)
+ }
+ )
+ )
+}
+
+interface BookDetailModalParams {
+ book: Book.Book
+ onClose: () => void
+}
+
+function bookDetailModal({ book, onClose }: BookDetailModalParams): Html {
+ return Modal.view({
+ content: h('div',
+ { className: 'g-BookDetail' },
+ h('div',
+ h('div', { className: 'g-BookDetail__Title' }, `${book.title}, ${book.date}`),
+ book.subtitle && h('div', { className: 'g-BookDetail__Subtitle' }, book.subtitle),
+ book.authors.join(', '),
+ h('div',
+ { className: 'g-BookDetail__Genres' },
+ book.genres.length > 1 ? 'Genres : ' : 'Genre : ',
+ book.genres.join(', ')
+ )
+ ),
+ h('img', { src: book.cover })
+ ),
+ onClose
+ })
+}
diff --git a/src/view/components/modal.ts b/src/view/components/modal.ts
new file mode 100644
index 0000000..fe08272
--- /dev/null
+++ b/src/view/components/modal.ts
@@ -0,0 +1,26 @@
+import { h, Html } from 'lib/rx'
+
+interface Params {
+ content: Html,
+ onClose: () => void
+}
+
+export function view({ content, onClose }: Params): Html {
+ return h('div',
+ { className: 'g-Modal',
+ onclick: () => onClose()
+ },
+ h('div',
+ { className: 'g-Modal__Content',
+ onclick: (e: Event) => e.stopPropagation()
+ },
+ h('button',
+ { className: 'g-Modal__Close',
+ onclick: () => onClose()
+ },
+ '✖'
+ ),
+ content
+ )
+ )
+}