From 8c5bd0bcb7a24dd1764312227758acfea0b993eb Mon Sep 17 00:00:00 2001 From: HackYourFuture Date: Wed, 18 Feb 2026 20:57:20 +0100 Subject: [PATCH] updated --- reading-list-manager/.prettierrc | 5 + reading-list-manager/app.js | 19 +++- reading-list-manager/books.json | 38 +++++++- reading-list-manager/package-lock.json | 96 +++++++++++++++++++ reading-list-manager/package.json | 18 ++++ reading-list-manager/readingList.js | 124 ++++++++++++++++++------- 6 files changed, 265 insertions(+), 35 deletions(-) create mode 100644 reading-list-manager/.prettierrc create mode 100644 reading-list-manager/package-lock.json create mode 100644 reading-list-manager/package.json diff --git a/reading-list-manager/.prettierrc b/reading-list-manager/.prettierrc new file mode 100644 index 0000000..0504489 --- /dev/null +++ b/reading-list-manager/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "trailingComma": "es5", + "printWidth": 80 +} diff --git a/reading-list-manager/app.js b/reading-list-manager/app.js index b0365ef..d42ca73 100644 --- a/reading-list-manager/app.js +++ b/reading-list-manager/app.js @@ -8,6 +8,23 @@ // 4. Add example of filtering by genre or read/unread status // 5. Add example of marking a book as read +import chalk from 'chalk'; +import * as readingListFunctions from './readingList.js'; + console.log('šŸ“š MY READING LIST šŸ“š\n'); -// Your implementation here +console.log('All Books:'); +readingListFunctions.printAllBooks(); + +readingListFunctions.printSummary(); + +console.log(chalk.magenta('\nšŸ“– UNREAD BOOKS EXAMPLE (uses filter()):')); +const unreadBooksArray = readingListFunctions.getUnreadBooks(); +console.log('Unread books count:', unreadBooksArray.length); + +console.log(chalk.magenta('\nšŸ“– MARKING BOOK AS READ EXAMPLE (uses map()):')); +const duneBookId = 2; +readingListFunctions.markAsRead(duneBookId); +console.log(chalk.green('āœ… Book marked as read!')); + +console.log(chalk.green('\nāœ… All 5 TODOs demonstrated!')); diff --git a/reading-list-manager/books.json b/reading-list-manager/books.json index 0637a08..e923bec 100644 --- a/reading-list-manager/books.json +++ b/reading-list-manager/books.json @@ -1 +1,37 @@ -[] \ No newline at end of file +[ + { + "id": 1, + "title": "1984", + "author": "George Orwell", + "genre": "Fiction", + "read": true + }, + { + "id": 2, + "title": "Dune", + "author": "Frank Herbert", + "genre": "Sci-Fi", + "read": true + }, + { + "id": 3, + "title": "The Hobbit", + "author": "J.R.R. Tolkien", + "genre": "Fantasy", + "read": true + }, + { + "id": 4, + "title": "Clean Code", + "author": "Robert C. Martin", + "genre": "Tech", + "read": false + }, + { + "id": 5, + "title": "Sapiens", + "author": "Yuval Noah Harari", + "genre": "History", + "read": true + } +] \ No newline at end of file diff --git a/reading-list-manager/package-lock.json b/reading-list-manager/package-lock.json new file mode 100644 index 0000000..53cca08 --- /dev/null +++ b/reading-list-manager/package-lock.json @@ -0,0 +1,96 @@ +{ + "name": "reading-list-manager", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "reading-list-manager", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "chalk": "^4.1.2", + "readline-sync": "^1.4.10" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/readline-sync": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", + "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/reading-list-manager/package.json b/reading-list-manager/package.json new file mode 100644 index 0000000..11b0da4 --- /dev/null +++ b/reading-list-manager/package.json @@ -0,0 +1,18 @@ +{ + "name": "reading-list-manager", + "version": "1.0.0", + "description": "", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node app.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "module", + "dependencies": { + "chalk": "^4.1.2", + "readline-sync": "^1.4.10" + } +} diff --git a/reading-list-manager/readingList.js b/reading-list-manager/readingList.js index 84febab..9f5e980 100644 --- a/reading-list-manager/readingList.js +++ b/reading-list-manager/readingList.js @@ -1,53 +1,111 @@ // Place here the file operation functions for loading and saving books +import fs from 'fs'; +import chalk from 'chalk'; -function loadBooks() { - // TODO: Implement this function - // Read from books.json - // Handle missing file (create empty array) - // Handle invalid JSON (notify user, use empty array) - // Use try-catch for error handling +const BOOKS_FILE = 'books.json'; + +export function loadBooks() { + try { + // Check if file exists first + if (!fs.existsSync(BOOKS_FILE)) { + console.log('No books.json found, starting empty'); + return []; + } + + // Read and parse the file + const data = fs.readFileSync(BOOKS_FILE, 'utf8'); + const books = JSON.parse(data); + + // Make sure it's an array + if (Array.isArray(books)) { + return books; + } else { + console.log('books.json is not valid, starting empty'); + return []; + } + } catch (error) { + console.log('Error loading books:', error.message); + return []; + } } -function saveBooks(books) { - // TODO: Implement this function - // Write books array to books.json - // Use try-catch for error handling +export function saveBooks(books) { + try { + fs.writeFileSync(BOOKS_FILE, JSON.stringify(books, null, 2)); + } catch (error) { + console.log('Error saving books:', error.message); + } } -function addBook(book) { - // TODO: Implement this function +export function addBook(bookInfo) { + const books = loadBooks(); + const newId = books.length + 1; + const newBook = { + id: newId, + title: bookInfo.title, + author: bookInfo.author, + genre: bookInfo.genre, + read: false + }; + books.push(newBook); + saveBooks(books); + return newBook; } -function getUnreadBooks() { - // TODO: Implement this function using filter() +export function getUnreadBooks() { + // TODO: Use filter() + const books = loadBooks(); + return books.filter(book => !book.read); } -function getBooksByGenre(genre) { - // TODO: Implement this function using filter() +export function getBooksByGenre(genre) { + // TODO: Use filter() + const books = loadBooks(); + return books.filter(book => book.genre === genre); } -function markAsRead(id) { - // TODO: Implement this function using map() +export function markAsRead(id) { + // TODO: Use map() + const books = loadBooks(); + const newBooks = books.map(book => { + if (book.id === id) { + return { ...book, read: true }; + } + return book; + }); + saveBooks(newBooks); + return newBooks; } -function getTotalBooks() { - // TODO: Implement this function using length +export function getTotalBooks() { + // TODO: Use length + return loadBooks().length; } -function hasUnreadBooks() { - // TODO: Implement this function using some() +export function hasUnreadBooks() { + // TODO: Use some() + return loadBooks().some(book => !book.read); } -function printAllBooks() { - // TODO: Implement this function - // Loop through and display with chalk - // Use green for read books, yellow for unread - // Use cyan for titles +export function printAllBooks() { + // Loop with chalk colors + const books = loadBooks(); + books.forEach(book => { + const symbol = book.read ? chalk.green('āœ“') : chalk.yellow('⚠'); + const titleColor = chalk.cyan(book.title); + const status = book.read ? chalk.green('Read') : chalk.yellow('Unread'); + + console.log(`${book.id}. ${titleColor} by ${book.author} (${book.genre}) ${symbol} ${status}`); + }); } -function printSummary() { - // TODO: Implement this function - // Show statistics with chalk - // Display total books, read count, unread count - // Use bold for stats -} \ No newline at end of file +export function printSummary() { + const books = loadBooks(); + const readCount = books.filter(book => book.read).length; + const unreadCount = books.length - readCount; + + console.log(chalk.bold('\nšŸ“Š SUMMARY')); + console.log(chalk.bold(`Total: ${books.length}`)); + console.log(chalk.green.bold(`Read: ${readCount}`)); + console.log(chalk.yellow.bold(`Unread: ${unreadCount}`)); +}