import { h, withVar, mount, Rx } from 'lib/rx' // Model interface Book { title: string authors: Array authorsSort: string genres: Array date: string read: ReadStatus, cover: string } type ReadStatus = 'Read' | 'Unread' | 'Reading' | 'Stopped' const readStatuses: Array = ['Read', 'Unread', 'Reading', 'Stopped' ] // Books // @ts-ignore const sortedBookLibrary: Array = (bookLibrary as Array).sort((a, b) => a.authorsSort == b.authorsSort ? a.date > b.date : a.authorsSort > b.authorsSort) // Filters interface Filters { read?: ReadStatus } // View const view = withVar({}, (filters, updateFilters) => { const filtredBooks = filters.map(f => sortedBookLibrary.filter(book => f.read === undefined || book.read === f.read ) ) return [ h('aside', viewFilters({ filtredBooks, filters, updateFilters })), h('main', h('header', filtredBooks.map(fb => `${fb.length} livres`)), h('div', { className: 'g-Books' }, filtredBooks.map(fb => fb.map(book => h('img', { className: 'g-Book', src: book.cover })) ) ) ) ] }) // Filters view interface ViewFiltersParams { filtredBooks: Rx> filters: Rx updateFilters: (f: (filters: Filters) => Filters) => void } function viewFilters({ filtredBooks, filters, updateFilters }: ViewFiltersParams) { return h('ul', {}, h('li', [ h('div', { className: 'g-FilterTitle' }, 'Lecture'), readFilter({ filtredBooks, readStatus: filters.map(fs => fs.read), update: (status?: ReadStatus) => updateFilters(fs => { fs.read = status return fs }) }) ]) ) } interface ReadFilterParams { filtredBooks: Rx> readStatus: Rx update: (status?: ReadStatus) => void } function readFilter({ filtredBooks, readStatus, update }: ReadFilterParams) { return h('ul', { className: 'g-Filters' }, readStatus.map(currentStatus => { if (currentStatus !== undefined) { return h('li', { className: 'g-Filter g-Filter--Selected' }, h('button', { onclick: () => update(undefined) }, readStatusLabel(currentStatus) ) ) } else { return readStatuses.map(status => { const count = filtredBooks.map(xs => xs.filter(b => b.read === status).length) return h('li', { className: 'g-Filter g-Filter--Unselected' }, h('button', { onclick: () => update(status) }, count.map(c => `${readStatusLabel(status)} (${c})`) ) ) }) } }) ) } function readStatusLabel(status: ReadStatus): string { if (status === 'Read') { return 'lus' } else if (status === 'Unread') { return 'non lus' } else if (status === 'Reading') { return 'en cours' } else { return 'arrêtés' } } mount(view)