├── .gitignore ├── modules ├── currentDate.js ├── dateTime.js └── books.js ├── .stylelintrc.json ├── .hintrc ├── .eslintrc.json ├── package.json ├── index.js ├── README.md ├── .github └── workflows │ └── linters.yml ├── index.html └── index.css /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /modules/currentDate.js: -------------------------------------------------------------------------------- 1 | import { DateTime } from './luxon.js'; 2 | 3 | const currentDate = DateTime.now().toLocaleString(DateTime.DATETIME_MED); 4 | 5 | export default currentDate; -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard"], 3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"], 4 | "rules": { 5 | "at-rule-no-unknown": null, 6 | "scss/at-rule-no-unknown": true, 7 | "csstree/validator": true 8 | }, 9 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css"] 10 | } 11 | -------------------------------------------------------------------------------- /.hintrc: -------------------------------------------------------------------------------- 1 | { 2 | "connector": { 3 | "name": "local", 4 | "options": { 5 | "pattern": ["**", "!.git/**", "!node_modules/**"] 6 | } 7 | }, 8 | "extends": ["development"], 9 | "formatters": ["stylish"], 10 | "hints": [ 11 | "button-type", 12 | "disown-opener", 13 | "html-checker", 14 | "meta-charset-utf-8", 15 | "meta-viewport", 16 | "no-inline-styles:error" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "parser": "babel-eslint", 8 | "parserOptions": { 9 | "ecmaVersion": 2018, 10 | "sourceType": "module" 11 | }, 12 | "extends": ["airbnb-base"], 13 | "rules": { 14 | "no-shadow": "off", 15 | "no-param-reassign": "off", 16 | "no-use-before-define": "off", 17 | "eol-last": "off", 18 | "import/extensions": [ 1, { 19 | "js": "always", "json": "always" 20 | }] 21 | }, 22 | "ignorePatterns": [ 23 | "dist/", 24 | "build/" 25 | ] 26 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "awesome-books-with-es6", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/divinecharlotte/Awesome-books-with-ES6.git" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/divinecharlotte/Awesome-books-with-ES6/issues" 18 | }, 19 | "homepage": "https://github.com/divinecharlotte/Awesome-books-with-ES6#readme", 20 | "devDependencies": { 21 | "babel-eslint": "^10.1.0", 22 | "eslint": "^7.32.0", 23 | "eslint-config-airbnb-base": "^14.2.1", 24 | "eslint-plugin-import": "^2.26.0", 25 | "stylelint": "^13.13.1", 26 | "stylelint-config-standard": "^21.0.0", 27 | "stylelint-csstree-validator": "^1.9.0", 28 | "stylelint-scss": "^3.21.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /modules/dateTime.js: -------------------------------------------------------------------------------- 1 | const handleTime = () => { 2 | const dateContainer = document.querySelector('.date-container'); 3 | const dateFunc = new Date(); 4 | const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; 5 | const year = dateFunc.getFullYear(); 6 | const month = months[dateFunc.getMonth()]; 7 | let currentDate = dateFunc.getDate(); 8 | const hour = dateFunc.getHours(); 9 | const minutes = dateFunc.getMinutes(); 10 | const second = dateFunc.getSeconds(); 11 | if (currentDate === 1) currentDate = 'first'; 12 | else if (currentDate === 2) currentDate = 'second'; 13 | else if (currentDate === 3) currentDate = 'third'; 14 | else currentDate += 'th'; 15 | 16 | const time = (hour < 12) ? `${month} ${currentDate} ${year}, ${hour} ${minutes} ${second} AM` 17 | : `${month} ${currentDate} ${year}, ${hour}: ${minutes}: ${second} PM`; 18 | dateContainer.innerHTML = time; 19 | }; 20 | export default handleTime; 21 | -------------------------------------------------------------------------------- /modules/books.js: -------------------------------------------------------------------------------- 1 | class Book { 2 | constructor() { 3 | this.books = JSON.parse(localStorage.getItem('Bookstore')) || []; 4 | } 5 | 6 | addBook(title, author) { 7 | this.books.push({ title, author }); 8 | this.storeBookData(); 9 | this.addBookToList(); 10 | } 11 | 12 | addBookToList() { 13 | const table = document.querySelector('#book-list'); 14 | let listOfBooks = ''; 15 | this.books.forEach((book, index) => { 16 | listOfBooks += ` 17 | 18 | "${book.title}" by ${book.author} 19 | 20 | `; 21 | }); 22 | table.innerHTML = listOfBooks; 23 | if (this.books.length > 0) { 24 | const deleteButtons = document.querySelectorAll('.delete'); 25 | deleteButtons.forEach((btn) => { btn.addEventListener('click', this.deleteBook.bind(this)); }); 26 | } 27 | } 28 | 29 | deleteBook(click) { 30 | const bookId = click.target.id; 31 | this.books.splice(bookId, 1); 32 | this.storeBookData(); 33 | this.addBookToList(); 34 | } 35 | 36 | storeBookData() { 37 | const bookdata = JSON.stringify(this.books); 38 | localStorage.setItem('Bookstore', bookdata); 39 | } 40 | } 41 | 42 | export default Book; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import Book from './modules/books.js'; 2 | import handleTime from './modules/dateTime.js'; 3 | 4 | window.addEventListener('load', () => { 5 | handleTime(); 6 | }); 7 | 8 | const Bookstore = new Book(); 9 | 10 | window.onload = () => { Bookstore.addBookToList(); }; 11 | 12 | document.querySelector('#book-form').addEventListener('submit', (e) => { 13 | e.preventDefault(); 14 | const title = document.querySelector('#title'); 15 | const author = document.querySelector('#tuthor'); 16 | Bookstore.addBook(title.value, author.value); 17 | title.value = ''; 18 | author.value = ''; 19 | }); 20 | 21 | const list = document.querySelector('#n1'); 22 | const addBook = document.querySelector('#n2'); 23 | const contactUs = document.querySelector('#n3'); 24 | 25 | list.addEventListener('click', () => { 26 | document.getElementById('show-book').style.cssText = 'display: flex;'; 27 | document.getElementById('book-form').style.cssText = 'display: none;'; 28 | document.getElementById('show-contact').style.cssText = 'display: none;'; 29 | }); 30 | 31 | addBook.addEventListener('click', () => { 32 | document.getElementById('show-book').style.cssText = 'display: none;'; 33 | document.getElementById('book-form').style.cssText = 'display: flex;'; 34 | document.getElementById('show-contact').style.cssText = 'display: none;'; 35 | }); 36 | 37 | contactUs.addEventListener('click', () => { 38 | document.getElementById('show-book').style.cssText = 'display: none;'; 39 | document.getElementById('book-form').style.cssText = 'display: none;'; 40 | document.getElementById('show-contact').style.cssText = 'display: flex;'; 41 | }); 42 | 43 | export default { list, addBook, contactUs }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Awesome-books-with-ES6 2 | 3 | > This project is about building a book keeping website. Where folks can store their favortie book names. And can also delete those, whenever, needed. 4 | ![aweso](https://user-images.githubusercontent.com/60146030/210275906-79c71ca6-b85d-4082-803b-d9c0419b77bf.PNG) 5 | 6 | ## Live demo 7 | [Live Demo]( https://divinecharlotte.github.io/Awesome-books-with-ES6/) 8 | 9 | 10 | ## Built With 11 | 12 | - Lighthouse (An open-source, automated tool for improving the quality of web pages. It has audits for performance, accessibility, progressive web apps, SEO and more). 13 | 14 | - Webhint (A customizable linting tool that helps you improve your site's accessibility, speed, cross-browser compatibility, and more by checking your code for best practices and common errors). 15 | 16 | - Stylelint (A mighty, modern linter that helps you avoid errors and enforce conventions in your styles). 17 | 18 | ### Prerequisites 19 | 20 | ## VScode or other editor 21 | 22 | ### Install 23 | 24 | #### Cloning the project 25 | 26 | 27 | ``` bash 28 | git clone https://github.com/iambenkis/Awesome-books-with-ES6.git 29 | ``` 30 | 31 | 32 | ##### For validation detection using Stylelint Run 33 | ``` bash 34 | npx stylelint "**/*.{css,scss}" 35 | ``` 36 | 37 | ## Getting packages and debuging with Webhint 38 | 39 | npm init -y 40 | npm install --save-dev hint@6.x 41 | 42 | ##### For validation detection using Webhint Run 43 | 44 | npx hint . 45 | 46 | ## Author 47 | 48 | 👤 **Divine Charlotte** 49 | 50 | - GitHub: [@Divine](https://github.com/divinecharlotte) 51 | - LinkedIn: [Divine Charlotte](https://www.linkedin.com/in/safar-ali999/) 52 | 53 | ## 🤝 Contributing 54 | 55 | Contributions, issues, and feature requests are welcome! 56 | 57 | Feel free to check the [issues page](https://github.com/divinecharlotte/Awesome-books-with-ES6/issues). 58 | 59 | ## Show your support 60 | 61 | Give a ⭐️ if you like this project! 62 | 63 | ## Acknowledgments 64 | 65 | - This project was inspired by [Microverse](https://www.microverse.org) 66 | 67 | 68 | -------------------------------------------------------------------------------- /.github/workflows/linters.yml: -------------------------------------------------------------------------------- 1 | name: Linters 2 | 3 | on: pull_request 4 | 5 | env: 6 | FORCE_COLOR: 1 7 | 8 | jobs: 9 | lighthouse: 10 | name: Lighthouse 11 | runs-on: ubuntu-18.04 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: "12.x" 17 | - name: Setup Lighthouse 18 | run: npm install -g @lhci/cli@0.7.x 19 | - name: Lighthouse Report 20 | run: lhci autorun --upload.target=temporary-public-storage --collect.staticDistDir=. 21 | webhint: 22 | name: Webhint 23 | runs-on: ubuntu-18.04 24 | steps: 25 | - uses: actions/checkout@v2 26 | - uses: actions/setup-node@v1 27 | with: 28 | node-version: "12.x" 29 | - name: Setup Webhint 30 | run: | 31 | npm install --save-dev hint@6.x 32 | [ -f .hintrc ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.hintrc 33 | - name: Webhint Report 34 | run: npx hint . 35 | stylelint: 36 | name: Stylelint 37 | runs-on: ubuntu-18.04 38 | steps: 39 | - uses: actions/checkout@v2 40 | - uses: actions/setup-node@v1 41 | with: 42 | node-version: "12.x" 43 | - name: Setup Stylelint 44 | run: | 45 | npm install --save-dev stylelint@13.x stylelint-scss@3.x stylelint-config-standard@21.x stylelint-csstree-validator@1.x 46 | [ -f .stylelintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.stylelintrc.json 47 | - name: Stylelint Report 48 | run: npx stylelint "**/*.{css,scss}" 49 | eslint: 50 | name: ESLint 51 | runs-on: ubuntu-18.04 52 | steps: 53 | - uses: actions/checkout@v2 54 | - uses: actions/setup-node@v1 55 | with: 56 | node-version: "12.x" 57 | - name: Setup ESLint 58 | run: | 59 | npm install --save-dev eslint@7.x eslint-config-airbnb-base@14.x eslint-plugin-import@2.x babel-eslint@10.x 60 | [ -f .eslintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.eslintrc.json 61 | - name: ESLint Report 62 | run: npx eslint . -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Book Keeping Website 9 | 10 | 11 | 27 |
28 |
29 | 30 |
31 |

All Awesome books

32 |
33 | 34 | 35 |
36 |
37 |
38 | 39 |
40 |
41 |

42 | Add a new book 43 |

44 |

45 |

46 | 47 |
48 |
49 |
50 |

Contact Information

51 |
52 |

If you have any sort of questions, Or want to share your valuable comments, Fell free to reach us at!

53 |
54 |
55 |
    56 |
  • Our Email: 123@gmail.com
  • 57 |
  • Our phone number: +283498723432
  • 58 |
  • Our address: Street 2, Hazara Town, New York
  • 59 |
60 |
61 |
62 |
63 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /index.css: -------------------------------------------------------------------------------- 1 | #bookss { 2 | display: flex; 3 | width: 70%; 4 | align-items: center; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-content: center; 8 | margin: 0 auto; 9 | } 10 | 11 | #dynamic { 12 | border: black 2px solid; 13 | } 14 | 15 | hr { 16 | width: 40%; 17 | height: 2px; 18 | background-color: black; 19 | } 20 | 21 | .table { 22 | width: 100%; 23 | } 24 | 25 | .delete { 26 | margin-left: 260px; 27 | } 28 | 29 | #book-list tr:nth-child(odd) { 30 | background-color: #e4e4e4; 31 | } 32 | 33 | #book-list td, 34 | #book-list th { 35 | padding: 4px; 36 | } 37 | 38 | table { 39 | border-collapse: collapse; 40 | } 41 | 42 | button { 43 | background-color: white; 44 | border-right: 4px solid black; 45 | border-bottom: 4px solid black; 46 | } 47 | 48 | form button { 49 | float: right; 50 | width: 100px; 51 | height: 40px; 52 | font-size: 25px; 53 | } 54 | 55 | section h1 { 56 | display: flex; 57 | justify-content: center; 58 | align-items: center; 59 | align-content: center; 60 | } 61 | 62 | nav #navigation { 63 | border: 3px black solid; 64 | display: flex; 65 | justify-content: space-between; 66 | align-content: center; 67 | align-items: center; 68 | padding-left: 3%; 69 | padding-right: 3%; 70 | height: 50px; 71 | margin-bottom: 150px; 72 | } 73 | 74 | nav ul { 75 | display: flex; 76 | gap: 30px; 77 | align-items: center; 78 | justify-content: center; 79 | align-content: center; 80 | } 81 | 82 | nav ul li a { 83 | text-decoration: none; 84 | color: black; 85 | } 86 | 87 | nav ul li { 88 | list-style-type: none; 89 | font-size: 20px; 90 | } 91 | 92 | nav ul hr { 93 | height: 30px; 94 | } 95 | 96 | nav ul li a:hover { 97 | color: blue; 98 | } 99 | 100 | #show-contact { 101 | align-items: center; 102 | flex-direction: column; 103 | display: none; 104 | } 105 | 106 | footer { 107 | border: 3px black solid; 108 | display: flex; 109 | align-items: center; 110 | justify-content: flex-start; 111 | gap: 43px; 112 | padding-left: 3%; 113 | height: 50px; 114 | width: 96%; 115 | margin: 0 auto; 116 | position: fixed; 117 | bottom: 0; 118 | left: 0; 119 | right: 0; 120 | } 121 | 122 | #book-form { 123 | font-size: 25px; 124 | display: none; 125 | align-items: center; 126 | justify-content: center; 127 | align-content: center; 128 | flex-direction: column; 129 | } 130 | 131 | #book-form input { 132 | width: 500px; 133 | height: 25px; 134 | border: 2px black solid; 135 | } 136 | 137 | section #show-book { 138 | justify-content: center; 139 | align-items: center; 140 | flex-direction: column; 141 | align-content: center; 142 | } 143 | 144 | .remove-page { 145 | display: flex; 146 | } 147 | 148 | .date-section { 149 | float: right; 150 | margin-top: -140px; 151 | } 152 | --------------------------------------------------------------------------------