diff --git a/assets/1984.png b/assets/1984.png new file mode 100644 index 0000000..e8c7e94 Binary files /dev/null and b/assets/1984.png differ diff --git a/assets/amelie.png b/assets/amelie.png new file mode 100644 index 0000000..c8cb449 Binary files /dev/null and b/assets/amelie.png differ diff --git a/assets/catcher.png b/assets/catcher.png new file mode 100644 index 0000000..c11dfb1 Binary files /dev/null and b/assets/catcher.png differ diff --git a/assets/devops.png b/assets/devops.png new file mode 100644 index 0000000..12a861a Binary files /dev/null and b/assets/devops.png differ diff --git a/assets/getsby.png b/assets/getsby.png new file mode 100644 index 0000000..715f880 Binary files /dev/null and b/assets/getsby.png differ diff --git a/assets/graf.png b/assets/graf.png new file mode 100644 index 0000000..02629e1 Binary files /dev/null and b/assets/graf.png differ diff --git a/assets/hobbit.png b/assets/hobbit.png new file mode 100644 index 0000000..809502f Binary files /dev/null and b/assets/hobbit.png differ diff --git a/assets/method.png b/assets/method.png new file mode 100644 index 0000000..e0634bd Binary files /dev/null and b/assets/method.png differ diff --git a/assets/physics.png b/assets/physics.png new file mode 100644 index 0000000..d6491cc Binary files /dev/null and b/assets/physics.png differ diff --git a/assets/sapiens.png b/assets/sapiens.png new file mode 100644 index 0000000..824f4bc Binary files /dev/null and b/assets/sapiens.png differ diff --git a/assets/sunMachine.png b/assets/sunMachine.png new file mode 100644 index 0000000..5873ef6 Binary files /dev/null and b/assets/sunMachine.png differ diff --git a/assets/toKill.png b/assets/toKill.png new file mode 100644 index 0000000..ef07b75 Binary files /dev/null and b/assets/toKill.png differ diff --git a/assets/zarathustra.png b/assets/zarathustra.png new file mode 100644 index 0000000..1790920 Binary files /dev/null and b/assets/zarathustra.png differ diff --git a/data/books.json b/data/books.json new file mode 100644 index 0000000..0819c47 --- /dev/null +++ b/data/books.json @@ -0,0 +1,101 @@ +[ + { + "title": "The DevOps handbook", + "author": "Gene Kim", + "genre": "Scientific", + "year": 2016, + "language": "English", + "image": "assets/devops.png", + "description": "Increase profitability, elevate work culture, and exceed productivity goals through DevOps practices." + }, + { + "title": "Graf Monte-Cristo", + "author": "Alexandre Dumas", + "genre": "Adventure", + "year": 1844, + "language": "French", + "image": "assets/graf.png", + "description": "Revenge and redemption tale." + }, + { + "title": "Discourse on Method", + "author": "Rene Descartes", + "genre": "Philosophy", + "year": 1637, + "language": "French", + "image": "assets/method.png", + "description": "Foundation of modern philosophy." + }, + { + "title": "Thus Spoke Zarathustra", + "author": "Friedrich Nietzsche", + "genre": "Philosophy", + "year": 1883, + "language": "German", + "image": "assets/zarathustra.png", + "description": "Philosophical novel by Nietzsche." + }, + { + "title": "Сонячна Машина", + "author": "Володимир Винниченко", + "genre": "Novel", + "year": 1928, + "language": "Українська", + "image": "assets/sunMachine.png", + "description": "Сонячна машина» Володимира Винниченка — це утопічно-фантастичний роман про побудову нового суспільства." + }, + { + "title": "Загальний курс фізики", + "author": "Іван Кучерук", + "genre": "Scientific", + "year": 1999, + "language": "Українська", + "image": "assets/physics.png", + "description": "Перший том про молекулярну фізику." + }, + { + "title": "Amelie", + "author": "Jean-Pierre Jeunet", + "genre": "Romance", + "year": 2001, + "language": "French", + "image": "assets/amelie.png", + "description": "Film about a shy, imaginative young woman in Paris who finds joy in secretly improving the lives of others while quietly longing for love herself.." + }, + { + "title": "The Great Gatsby", + "author": "F. Scott Fitzgerald", + "genre": "Novel", + "year": 1925, + "language": "English", + "image": "assets/getsby.png", + "description": "A novel about the American dream." + }, + { + "title": "To Kill a Mockingbird", + "author": "Harper Lee", + "genre": "Drama", + "year": 1960, + "language": "English", + "image": "assets/toKill.png", + "description": "A story about racial injustice." + }, + { + "title": "1984", + "author": "George Orwell", + "genre": "Dystopian", + "year": 1949, + "language": "English", + "image": "assets/1984.png", + "description": "A vision of totalitarian future." + }, + { + "title": "The Hobbit", + "author": "J.R.R. Tolkien", + "genre": "Fantasy", + "year": 1937, + "language": "English", + "image": "assets/hobbit.png", + "description": "A journey through Middle-earth." + } +] \ No newline at end of file diff --git a/index.html b/index.html index 09c6dc0..3557724 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,71 @@ +
+

Online Book Library

+
+ + +
+ + + Звіт + +
+
+ + +
+
+

Pillar

+
+ +
+
+ +
+ +
+
+
+ + \ No newline at end of file diff --git a/report.html b/report.html new file mode 100644 index 0000000..1409b5a --- /dev/null +++ b/report.html @@ -0,0 +1,72 @@ + + + + + Звіт по книгах + + + + + + +
+

Звіт про книги

+ Назад до бібліотеки +
+ +
+ + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index e69de29..4b88e64 100644 --- a/src/main.js +++ b/src/main.js @@ -0,0 +1,327 @@ +document.addEventListener('DOMContentLoaded', () => { + const headerTitle = document.querySelector('.header-title'); + const bookListHeaderH2 = document.querySelector('.book-list-section .book-list-header h2'); + const filterSortControls = document.querySelector('.filter-sort-controls'); + const sortSelect = document.querySelector('.sort-by select'); + const favoritesButton = document.querySelector('.favorites-button'); + const backButton = document.querySelector('.back-button'); + + var genres = [] + var years = [] + var languages = [] + let allBooks = [] + let favoriteBooks = [] + + // For phones + const filterBtn = document.querySelector('.filter-btn'); + const sortBtn = document.querySelector('.sort-btn-mobile'); + + const sidebar = document.querySelector('.sidebar'); + var visible // for filters in phone + + + function applyResponsiveChanges() { + if (window.innerWidth >= 900) { + if (headerTitle) { + headerTitle.textContent = "Online Book Library"; + } + } + if (window.innerWidth < 900) { + if (headerTitle) { + headerTitle.textContent = "Online Library"; + } + + if (bookListHeaderH2) { + bookListHeaderH2.textContent = "Featured"; + } + + if (window.innerWidth < 600) { + bookListHeaderH2.textContent = "Featured Books"; + } + + if (signInButton) { + signInButton.style.display = 'none'; + } + + if (filterSortControls) { + filterSortControls.style.display = 'flex'; + } + + if (sortSelect) { + sortSelect.style.display = 'none'; + } + + } else { + if (bookListHeaderH2) { + bookListHeaderH2.textContent = "Pillar"; + } + + if (signInButton) { + signInButton.style.display = 'block'; + } + + if (filterSortControls) { + filterSortControls.style.display = 'none'; + } + + if (sortSelect) { + sortSelect.style.display = 'inline-block'; + } + } + } + + function loadBooks() { + fetch('./data/books.json') + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + return response.json(); + }) + .then(books => { + allBooks = books; + const bookGrid = document.querySelector('.book-grid'); + + books.forEach(book => { + if (!genres.includes(book.genre)) genres.push(book.genre); + if (!years.includes(book.year)) years.push(book.year); + if (!languages.includes(book.language)) languages.push(book.language); + + const bookCard = document.createElement('div'); + bookCard.classList.add('book-card'); + + bookCard.innerHTML = ` + ${book.title} Cover +
+

${book.title}

+

${book.author}

+
+ `; + + bookGrid.appendChild(bookCard); + }); + loadFilterPanel(); + }) + .catch(error => { + console.error('Error loading books:', error); + }); + } + + function loadFilterPanel() { + const filterGenre = document.getElementById('genre'); + const filterYear = document.getElementById('year'); + const filterLanguage = document.getElementById('language'); + + + genres.forEach(genre => { + const filter = document.createElement('div'); + filter.classList.add('filter-group'); + filter.innerHTML = ` + + `; + filterGenre.appendChild(filter); + }) + + years.forEach(year => { + const filter = document.createElement('div'); + filter.classList.add('filter-group'); + filter.innerHTML = ` + + `; + filterYear.appendChild(filter); + }) + + languages.forEach(language => { + const filter = document.createElement('div'); + filter.classList.add('filter-group'); + filter.innerHTML = ` + + `; + filterLanguage.appendChild(filter); + }) + + const authorInput = document.querySelector('.author-input'); + authorInput.addEventListener('input', filterBooks); + + if (sortSelect) { + sortSelect.addEventListener('change', filterBooks); + } + + if (sortBtn) { + sortBtn.addEventListener('change', filterBooks); + } + + if (filterBtn) { + filterBtn.addEventListener('click', showSidebarOverlay); + } + + document.querySelectorAll('.filter-section input').forEach(input => { + input.addEventListener('change', filterBooks); + }); + + document.querySelector('.close-button').addEventListener('click', () => { + document.getElementById('book-popup').classList.add('hidden'); + }); + + } + + function filterBooks() { + //Genres + const genreInputs = document.querySelectorAll('#genre input[type="checkbox"]:checked'); + const checkedGenres = []; + genreInputs.forEach(input => { + const genre = input.parentElement.textContent.trim(); + checkedGenres.push(genre); + }); + + //Years + const yearInputs = document.querySelectorAll('#year input[type="checkbox"]:checked'); + const checkedYears = []; + yearInputs.forEach(input => { + const year = parseInt(input.parentElement.textContent.trim()); + checkedYears.push(year); + }); + + //Languages + const langInputs = document.querySelectorAll('#language input[type="checkbox"]:checked'); + const checkedLanguages = []; + langInputs.forEach(input => { + const language = input.parentElement.textContent.trim(); + checkedLanguages.push(language); + }); + + //Input + const authorInput = document.querySelector('.author-input'); + const authorQuery = authorInput.value.trim().toLowerCase(); + + // Filtration + let filtered = allBooks.filter(book => + checkedGenres.includes(book.genre) && + checkedYears.includes(book.year) && + checkedLanguages.includes(book.language) && + (book.author.toLowerCase().includes(authorQuery) || authorQuery === "") + ); + + // Sort + const sortSelect = document.querySelector('.sort-by select'); + var sortParam = sortSelect ? sortSelect.value : ''; + // if (sortBtn) { + // sortParam = sortBtn.value + // } + filtered = sortBooks(filtered, sortParam); + + renderBooks(filtered); + } + + function renderBooks(books) { + const bookGrid = document.querySelector('.book-grid'); + bookGrid.innerHTML = ''; + + books.forEach(book => { + const bookCard = document.createElement('div'); + bookCard.classList.add('book-card'); + + bookCard.innerHTML = ` + ${book.title} Cover +
+

${book.title}

+

${book.author}

+
+ `; + bookGrid.appendChild(bookCard); + + bookCard.addEventListener('click', () => { + showPopup(book); + }); + }); + + } + + function sortBooks(books, parameter) { + const sortedBooks = [...books]; + + if (parameter === 'year') { + sortedBooks.sort((a, b) => a.year - b.year); + } else if (parameter === 'genre') { + sortedBooks.sort((a, b) => { + sortedBooks.sort((a, b) => a.genre.trim().toLowerCase().localeCompare(b.genre.trim().toLowerCase())); + }); + } + + return sortedBooks; + } + + function showPopup(book) { + const popup = document.getElementById('book-popup'); + document.getElementById('popup-image').src = book.image; + document.getElementById('popup-title').textContent = book.title; + document.getElementById('popup-author').textContent = "Author: " + book.author; + document.getElementById('popup-year').textContent = "Year: " + book.year; + document.getElementById('popup-language').textContent = "Language: " + book.language; + document.getElementById('popup-genre').textContent = "Genre: " + book.genre; + popup.classList.remove('hidden'); + + const favButton = document.getElementById('add-favorite-button'); + favButton.onclick = () => { + addToFavorites(book); + popup.classList.add('hidden'); + alert(`"${book.title}" додано до улюблених!`); + }; + } + + function addToFavorites(book) { + if (!favoriteBooks.find(b => b.title === book.title)) { + favoriteBooks.push(book); + localStorage.setItem("favoriteBooks", JSON.stringify(favoriteBooks)); + } + } + + function showSidebarOverlay() { + if (!visible) { + visible = true + sidebar.style.display = 'block'; + sidebar.backgroundColor = '#f8f8f8'; + sidebar.style.position = 'absolute'; + if (window.innerWidth <= 600) { + sidebar.style.top = '70px'; + sidebar.style.left = '0'; + } else { + sidebar.style.top = '90px'; + } + sidebar.style.left = '0'; + sidebar.style.width = '100%'; + sidebar.style.height = '1200px'; + sidebar.style.zIndex = '1000'; + sidebar.style.padding = '16px'; + sidebar.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; + } else { + sidebar.style.display = 'none'; + visible = false + } + } + + favoritesButton.addEventListener('click', () => { + renderBooks(favoriteBooks); + favoritesButton.classList.add('hidden'); + backButton.classList.remove('hidden'); + }); + + backButton.addEventListener('click', () => { + filterBooks(); + backButton.classList.add('hidden'); + favoritesButton.classList.remove('hidden'); + }); + + loadBooks(); + applyResponsiveChanges(); + window.addEventListener('resize', applyResponsiveChanges); +}); \ No newline at end of file diff --git a/style/style.css b/style/style.css index e69de29..41c5e5c 100644 --- a/style/style.css +++ b/style/style.css @@ -0,0 +1,499 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #fff; + color: #333; +} + +.container { + display: flex; + max-width: 1200px; + margin: 20px auto; + border-radius: 8px; + background-color: #fff; +} + +.report-button { + padding: 8px 16px; + background-color: #007acc; + color: white; + text-decoration: none; + border-radius: 4px; + margin-left: 10px; +} + +.report-button:hover { + background-color: #005fa3; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px; + background-color: #f8f8f8; + border-bottom: 1px solid #eee; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.header-title { + margin: 0; + color: #333; +} + +.sign-in-button { + background-color: #007bff; + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 16px; +} + +.favorites-button { + background-color: #8a273c; + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 16px; +} + +.back-button { + background-color: rgb(33, 104, 4); + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 16px; +} + +.hidden { + display: none; +} + +.sign-in-button:hover { + background-color: #0056b3; +} + +.filter-sort-controls { + display: none; + align-items: center; + gap: 10px; + font-size: 20px; +} +.filter-btn, .sort-btn-mobile { + background-color: #fff; + border: none; + padding: 8px 12px; + border-radius: 5px; + cursor: pointer; + font-size: 0.9em; + white-space: nowrap; +} +.sort-btn-mobile::after { content: " \25BC"; } + +.sidebar { + background-color: #f8f8f8; + width: 250px; + padding: 20px; +} + +.filter-section { + max-height: 600px; + background-color: #f8f8f8; + padding: 10px; +} + +.filter-section h2 { + margin-top: 0; + color: #555; +} + +.filter-group { + margin-bottom: 20px; +} + +.filter-group h3 { + margin-top: 0; + margin-bottom: 10px; + color: #666; + font-size: 1.1em; +} + +.checkbox-container { + display: block; + position: relative; + padding-left: 25px; + margin-bottom: 10px; + cursor: pointer; + font-size: 1em; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox-container input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; +} + +.checkmark { + position: absolute; + top: 0; + left: 0; + height: 18px; + width: 18px; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 3px; +} + +.checkbox-container input:checked ~ .checkmark { + background-color: #007bff; +} + +.checkmark:after { + content: ""; + position: absolute; + display: none; +} + +.checkbox-container input:checked ~ .checkmark:after { + display: block; +} + +.checkbox-container .checkmark:after { + left: 6px; + top: 2px; + width: 5px; + height: 10px; + border: solid white; + border-width: 0 3px 3px 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} + +.author-input { + width: calc(100% - 40px); + padding: 8px 10px; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 1em; +} + +.book-list-section { + flex-grow: 1; + padding: 20px; +} + +.book-list-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; +} + +.book-list-header h2 { + margin: 0; + color: #555; +} + +.sort-by span { + margin-right: 10px; + color: #666; +} + +.radio-container { + display: block; + position: relative; + padding-left: 25px; + margin-bottom: 10px; + cursor: pointer; + font-size: 1em; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.sort-by select { + padding: 8px 10px; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 0.9em; + background-size: 12px; + padding-right: 25px; +} + +.book-grid { + display: grid; + grid-template-columns: repeat(3, minmax(150px, 1fr)); + gap: 20px; + justify-content: center; +} + +.book-card { + background-color: #fff; + border-radius: 8px; + padding: 0; + text-align: center; + transition: transform 0.2s ease-in-out; + max-width: 150px; + justify-self: center; +} + +.book-card img { + width: 100%; + height: 200px; + object-fit: contain; + border-radius: 4px; + margin-bottom: 10px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + + +.book-title { + font-weight: bold; + margin: 5px 0; + color: #333; + font-size: 1.1em; +} + +.book-author { + color: #666; + font-size: 0.9em; +} + +/*попапчік лол*/ +.popup { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0.6); + display: flex; + justify-content: center; + align-items: center; + z-index: 999; +} + +.popup.hidden { + display: none; +} + +.popup-content { + background: white; + padding: 20px; + border-radius: 8px; + max-width: 400px; + text-align: center; + position: relative; +} + +.popup-content img { + max-width: 100%; + height: auto; +} + +.close-button { + position: absolute; + right: 15px; + top: 10px; + font-size: 24px; + cursor: pointer; +} +/*свіжина*/ + +@media (max-width: 900px) { + body { + font-family: Arial; + background-color: #efefef; + padding: 30px; + box-shadow: 0 0px 10px #888888; + } + + .container { + border-radius: 0px; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + flex-direction: column; + max-width: 100%; + margin: 0; + box-shadow: none; + background-color: #fff; + padding: 15px; + } + + .header { + border-top-left-radius: 10px; + border-top-right-radius: 10px; + padding: 15px; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #eee; + background-color: #fff; + } + + .header-title { + font-size: 1.2em; + order: 1; + flex-basis: auto; + text-align: left; + + } + + .sign-in-button { + display: none; + } + + .filter-sort-controls { + display: flex; + order: 2; + } + + .sidebar { + display: none; + } + + .book-list-section { + padding: 15px; + } + + .book-list-header { + flex-direction: column; + align-items: flex-start; + margin-bottom: 15px; + } + + .book-list-header h2 { + font-size: 1.2em; + margin-bottom: 10px; + content: "Featured"; + } + + .sort-by { + display: none; + } + + .book-grid { + grid-template-columns: repeat(2, 1fr); + gap: 15px; + } + + .book-card { + padding: 0; + } + + .book-card img { + height: 180px; + width: auto; + object-fit: contain; + } + + .book-title { + font-size: 1em; + padding: 0 10px; + } + + .book-author { + font-size: 0.85em; + padding: 0 10px 10px; + } +} + +@media (max-width: 600px) { + + body { + margin: 0; + padding: 0; + } + + .container { + flex-direction: column; + padding: 10px; + } + + .sidebar { + width: 100%; + } + + .book-grid { + grid-template-columns: repeat(1, 1fr); + width: 100%; + display: flex; + flex: 1; + flex-direction: column; + gap: 15px; + } + + .book-card { + display: flex; + flex: 1; + max-width: 100%; + width: 100%; + align-items: center; + background: #fff; + border-radius: 8px; + padding: 10px; + box-shadow: none; + } + + .book-card img { + width: 80px; + height: 120px; + object-fit: cover; + margin-right: 15px; + flex-shrink: 0; + } + + .book-details { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + } + + .book-title { + font-size: 16px; + font-weight: bold; + word-break: break-word; + } + + .book-author { + font-size: 14px; + color: #555; + margin-top: 5px; + } + + .filter-btn { + display: flex; + order: 2; + border: 1px solid #eee; + } + + .sort-btn-mobile { + display: flex; + order: 2; + border: 1px solid #eee; + } + + .sort-btn-mobile::after { + content: ""; + } +} + + +