import './generated.css' import Alpine from 'alpinejs' import persist from '@alpinejs/persist' window.Alpine = Alpine; Alpine.plugin(persist) Alpine.data('bookmeterList', () => ({ items: [], filteredItems: [], username: '', publisher: '', title: '', author: '', nameFilter: '', async init() { this.$watch('nameFilter', () => this.updateFilter()); this.$watch('username', () => this.updateFilter()); this.$watch('title', () => this.updateFilter()); this.$watch('author', () => this.updateFilter()); this.$watch('publisher', () => this.updateFilter()); let qp = new URLSearchParams(window.location.search); if(qp.get('filter')) this.nameFilter = qp.get('filter'); const res = await fetch('/posts.json') this.items = await res.json(); this.updateFilter(); }, stats(){ return { 'pages_total': this.filteredItems.reduce((a, b) => a + b.book.pages, 0) || '-', 'likes_total': this.filteredItems.reduce((a, b) => a + b.likes, 0) || '-', 'pages_avg': Math.round(this.filteredItems.reduce((a, b) => a + b.book.pages, 0)/this.filteredItems.length) || '-', 'likes_avg': Math.round(this.filteredItems.reduce((a, b) => a + b.likes, 0)/this.filteredItems.length) || '-', 'rating_avg': (this.filteredItems.reduce((a, b) => a + b.book.rating, 0)/this.filteredItems.length).toPrecision(2) || '-', 'formats': this.filteredItems.reduce((acc, item) => { let val = item.book.format.toLowerCase() || 'brak danych'; acc[val] = acc[val] === undefined ? 1 : acc[val] += 1; return acc; }, {}) }; }, updateFilter(){ let filter = this.nameFilter.toLowerCase(); this.filteredItems = this.items.filter(i => { return ( (!this.username || i.username.toLowerCase().includes(this.username.toLowerCase())) && (!this.title || i.book.title.toLowerCase().includes(this.title.toLowerCase())) && (!this.author || i.book.author.toLowerCase().includes(this.author.toLowerCase())) && (!this.publisher || i.book.publisher.toLowerCase().includes(this.publisher.toLowerCase())) ); if(filter.startsWith('@') && i.username.toLowerCase().includes(filter.substring(1))) return true; if (i.username.toLowerCase().includes(filter) || i.book.title.toLowerCase().includes(filter) || i.book.author.toLowerCase().includes(filter) || i.book.publisher.toLowerCase().includes(filter)) return true; return false; }); this.updateURL(); }, updateURL() { let qp = new URLSearchParams(); if(this.nameFilter !== '') qp.set('filter', this.nameFilter); history.replaceState(null, null, "?"+qp.toString()); } })) Alpine.start();