├── .gitignore
├── .vscode
└── settings.json
├── images
├── murple_logo.png
├── icons8-books-96.png
├── DesktopVersionADD.jpg
├── MobileVersionADD.jpg
├── MobileVersionLIST.jpg
├── MobileVersionMenu.jpg
├── DesktopVersionLIST.jpg
├── MobileVersionCONTACT.jpg
├── DesctopVersionCONTACT.jpg
├── facebook.svg
├── linkedin.svg
├── twitter.svg
├── instagram.svg
└── github.svg
├── module
├── dates.js
└── variables.js
├── package.json
├── .hintrc
├── .eslintrc.json
├── .stylelintrc.json
├── MIT.md
├── index.html
├── .github
└── workflows
│ └── linters.yml
├── index.js
├── index.css
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "liveServer.settings.port": 5501
3 | }
--------------------------------------------------------------------------------
/images/murple_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/murple_logo.png
--------------------------------------------------------------------------------
/images/icons8-books-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/icons8-books-96.png
--------------------------------------------------------------------------------
/images/DesktopVersionADD.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/DesktopVersionADD.jpg
--------------------------------------------------------------------------------
/images/MobileVersionADD.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/MobileVersionADD.jpg
--------------------------------------------------------------------------------
/images/MobileVersionLIST.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/MobileVersionLIST.jpg
--------------------------------------------------------------------------------
/images/MobileVersionMenu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/MobileVersionMenu.jpg
--------------------------------------------------------------------------------
/images/DesktopVersionLIST.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/DesktopVersionLIST.jpg
--------------------------------------------------------------------------------
/images/MobileVersionCONTACT.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/MobileVersionCONTACT.jpg
--------------------------------------------------------------------------------
/images/DesctopVersionCONTACT.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lucas-Erkana/Awesome_Book/HEAD/images/DesctopVersionCONTACT.jpg
--------------------------------------------------------------------------------
/module/dates.js:
--------------------------------------------------------------------------------
1 | import { DateTime } from './luxon.js';
2 |
3 | const dateDisplay = document.querySelector('.date1');
4 | const setTime = () => {
5 | const now = DateTime.now();
6 | const date = now.toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS);
7 | dateDisplay.textContent = date;
8 | };
9 |
10 | setInterval(setTime, 1000);
11 |
12 | export default setTime;
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "babel-eslint": "^10.1.0",
4 | "eslint": "^7.32.0",
5 | "eslint-config-airbnb-base": "^14.2.1",
6 | "eslint-plugin-import": "^2.26.0",
7 | "stylelint": "^13.13.1",
8 | "stylelint-config-standard": "^21.0.0",
9 | "stylelint-csstree-validator": "^1.9.0",
10 | "stylelint-scss": "^3.21.0"
11 | },
12 | "dependencies": {
13 | "luxon": "^3.1.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/images/facebook.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.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 | "max-classes-per-file":0,
15 | "no-shadow": "off",
16 | "no-param-reassign": "off",
17 | "eol-last": "off",
18 | "import/prefer-default-export": 0,
19 | "import/extensions": [ 1, {
20 | "js": "always", "json": "always"
21 | }]
22 | },
23 | "ignorePatterns": [
24 | "dist/",
25 | "build/"
26 | ]
27 | }
--------------------------------------------------------------------------------
/.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": [
7 | true,
8 | {
9 | "ignoreAtRules": [
10 | "tailwind",
11 | "apply",
12 | "variants",
13 | "responsive",
14 | "screen"
15 | ]
16 | }
17 | ]
18 | },
19 | "csstree/validator": true,
20 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css"]
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/images/linkedin.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/module/variables.js:
--------------------------------------------------------------------------------
1 | export const form = document.querySelector('form');
2 | export const addButton = document.querySelector('.AddButton');
3 | export const titleInput = document.querySelector('.title-input');
4 | export const authorInput = document.querySelector('.author-input');
5 | export const booksContainer = document.querySelector('.Books__Section');
6 | export const listSectionBtn = document.querySelector('#list-btn');
7 | export const formSectionBtn = document.querySelector('#new-btn');
8 | export const contactSectionBtn = document.querySelector('#contact-btn');
9 | export const librarySection = document.querySelector('.library-section');
10 | export const formSection = document.querySelector('.form-section');
11 | export const contactSection = document.querySelector('.contact-section');
12 |
--------------------------------------------------------------------------------
/images/twitter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/MIT.md:
--------------------------------------------------------------------------------
1 | ## Copyright 2021, Lucas Erkana
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this [APP TYPE] and associated documentation files, to deal in the [APP TYPE] without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the [APP TYPE], and to permit persons to whom the [APP TYPE] is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the [APP TYPE].
6 |
7 | THE [APP TYPE] IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE [APP TYPE] OR THE USE OR OTHER DEALINGS IN THE [APP TYPE].
8 |
--------------------------------------------------------------------------------
/images/instagram.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Awesome Book List Project
11 |
12 |
13 |
14 |
15 |
16 |
17 | Awesome Books
18 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | All Awesome Books
30 |
31 |
32 |
40 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/.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-22.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-22.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@7.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-22.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-22.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 .
63 | nodechecker:
64 | name: node_modules checker
65 | runs-on: ubuntu-22.04
66 | steps:
67 | - uses: actions/checkout@v2
68 | - name: Check node_modules existence
69 | run: |
70 | if [ -d "node_modules/" ]; then echo -e "\e[1;31mThe node_modules/ folder was pushed to the repo. Please remove it from the GitHub repository and try again."; echo -e "\e[1;32mYou can set up a .gitignore file with this folder included on it to prevent this from happening in the future." && exit 1; fi
71 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | form,
3 | addButton,
4 | titleInput,
5 | authorInput,
6 | listSectionBtn,
7 | formSectionBtn,
8 | contactSectionBtn,
9 | librarySection,
10 | formSection,
11 | contactSection,
12 | booksContainer,
13 | } from './module/variables.js';
14 | // import * as dateNow from './module/dates.js';
15 | import setTime from './module/dates.js';
16 |
17 | let bookList = [];
18 | setTime();
19 | const localData = localStorage.getItem('bookList');
20 | if (localData !== null) {
21 | bookList = JSON.parse(localData);
22 | }
23 |
24 | const removeBook = (bookId) => {
25 | bookList = bookList.filter((book) => book.id !== parseInt(bookId, 10));
26 | };
27 |
28 | const storeBooks = () => {
29 | localStorage.setItem('bookList', JSON.stringify(bookList));
30 | };
31 |
32 | // eslint-disable-next-line no-unused-vars
33 | const updateBooks = () => {
34 | booksContainer.textContent = '';
35 | bookList.forEach((book) => {
36 | const booksSection = `
37 |
${book.title} by ${book.author}
38 |
Remove
39 |
`;
40 | booksContainer.innerHTML += booksSection;
41 | });
42 | const removeButtons = document.querySelectorAll('.remove-button');
43 | removeButtons.forEach((button) => button.addEventListener('click', (e) => {
44 | removeBook(e.target.id);
45 | updateBooks();
46 | }));
47 | storeBooks();
48 | };
49 |
50 | addButton.addEventListener('click', (e) => {
51 | e.preventDefault();
52 | const book = {
53 | id: Date.now(),
54 | title: titleInput.value,
55 | author: authorInput.value,
56 | };
57 | bookList.push(book);
58 | updateBooks();
59 | form.reset();
60 | });
61 |
62 | const toggleDisplaySection = (id) => {
63 | if (id === 'list-btn') {
64 | librarySection.classList.remove('hide');
65 | formSection.classList.add('hide');
66 | contactSection.classList.add('hide');
67 | } else if (id === 'new-btn') {
68 | librarySection.classList.add('hide');
69 | formSection.classList.remove('hide');
70 | contactSection.classList.add('hide');
71 | } else if (id === 'contact-btn') {
72 | librarySection.classList.add('hide');
73 | formSection.classList.add('hide');
74 | contactSection.classList.remove('hide');
75 | }
76 | };
77 |
78 | listSectionBtn.addEventListener('click', (e) => {
79 | e.preventDefault();
80 | toggleDisplaySection(e.target.id);
81 | });
82 |
83 | formSectionBtn.addEventListener('click', (e) => {
84 | e.preventDefault();
85 | toggleDisplaySection(e.target.id);
86 | });
87 |
88 | contactSectionBtn.addEventListener('click', (e) => {
89 | e.preventDefault();
90 | toggleDisplaySection(e.target.id);
91 | });
92 |
93 | if (localStorage.getItem('bookList')) {
94 | updateBooks();
95 | }
96 |
--------------------------------------------------------------------------------
/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | header {
7 | display: flex;
8 | flex-direction: column;
9 | }
10 |
11 | h2 {
12 | text-align: center;
13 | }
14 |
15 | section {
16 | min-height: 60vh;
17 | }
18 |
19 | .library-section {
20 | padding: 10px;
21 | }
22 |
23 | .Books__Section {
24 | display: flex;
25 | flex-direction: column;
26 | align-items: center;
27 | margin-bottom: 20px;
28 | border-bottom-style: solid;
29 | border-bottom-width: 2px;
30 | border-color: black;
31 | }
32 |
33 | .Book__section {
34 | display: flex;
35 | justify-content: space-between;
36 | gap: 300px;
37 | margin-bottom: 20px;
38 | }
39 |
40 | .Book__section-item {
41 | width: 200px;
42 | }
43 |
44 | .remove-button {
45 | padding: 10px 20px;
46 | background-color: grey;
47 | border-radius: 12px;
48 | border: 4px solid red;
49 | }
50 |
51 | .AddButton {
52 | padding: 10px 20px;
53 | background-color: gray;
54 | border-radius: 12px;
55 | align-self: flex-end;
56 | border: 4px solid green;
57 | width: 400px;
58 | }
59 |
60 | .title-input {
61 | width: 400px;
62 | padding: 10px 20px;
63 | }
64 |
65 | .author-input {
66 | width: 400px;
67 | padding: 10px 20px;
68 | }
69 |
70 | .form-section {
71 | padding: 10px;
72 | }
73 |
74 | form {
75 | display: flex;
76 | flex-direction: column;
77 | justify-content: center;
78 | align-items: center;
79 | gap: 10px;
80 | width: fit-content;
81 | margin: 0 auto;
82 | }
83 |
84 | .navlist {
85 | display: flex;
86 | justify-content: space-between;
87 | align-items: center;
88 | padding: 0 40px 20px 40px;
89 | border: 4px solid black;
90 | margin-top: 2px;
91 | background-color: black;
92 | color: white;
93 | }
94 |
95 | .nav-list {
96 | display: flex;
97 | gap: 30px;
98 | list-style: none;
99 | }
100 |
101 | .nav-list-item {
102 | text-decoration: none;
103 | color: whitesmoke;
104 | font-size: 20px;
105 | }
106 |
107 | .nav-list-item:hover {
108 | border-bottom: 2px solid white;
109 | }
110 |
111 | #list-btn :hover {
112 | background-color: blue;
113 | border-bottom: 2px solid blue;
114 | }
115 |
116 | .contact-section {
117 | display: flex;
118 | flex-direction: column;
119 | justify-content: center;
120 | align-items: center;
121 | margin: 0;
122 | padding: 5px 30px;
123 | }
124 |
125 | .contact-section-heading {
126 | text-align: center;
127 | }
128 |
129 | .date {
130 | display: flex;
131 | align-self: flex-end;
132 | padding: 0 30px;
133 | }
134 |
135 | .footer {
136 | text-align: left;
137 | font-weight: 600;
138 | font-size: 20px;
139 | background-color: black;
140 | padding: 30px 10px;
141 | border: 4px solid black;
142 | margin-bottom: auto;
143 | color: white;
144 | }
145 |
146 | .hide {
147 | display: none;
148 | }
149 |
150 | .date1 {
151 | text-align: end;
152 | padding: 20px 100px;
153 | font-size: 16px;
154 | font-weight: bold;
155 | }
156 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
Microverse
9 |
10 |
11 |
12 |
13 |
14 | # 📗 Table of Contents
15 |
16 | - [📖 About the Project](#about-project)
17 | - [🛠 Built With](#built-with)
18 | - [🚀 Live Demo](#live-demo)
19 | - [💻 Getting Started](#getting-started)
20 | - [👥 Authors](#authors)
21 | - [🔭 Future Features](#future-features)
22 | - [🤝 Contributing](#contributing)
23 | - [⭐️ Show your support](#support)
24 | - [🙏 Acknowledgements](#acknowledgements)
25 | - [📝 License](#license)
26 |
27 |
28 |
29 | # 📖 Awesome Book
30 |
31 |
32 | Desktop Version List
33 | Mobile Version List
34 | Mobile Version Menu
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | Add Desktop Version
43 | Add Mobile Version
44 | Contact Mobile Version
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | **Awesome books** is a simple website that displays a list of books and allows you to add and remove books from that list.
53 |
54 | Here are some features of the page:
55 |
56 | Add a book to your collection.
57 | Remove a book from your collection.
58 | Store your data history in the browser's memory.
59 |
60 |
61 |
62 |
63 | ## 🛠 Built With
64 | HTML
65 | CSS
66 | Javascript
67 |
68 |
69 | (back to top )
70 |
71 |
72 |
73 | ## 🚀 Live Demo
74 |
75 | [Awesome Book]( https://Lucas-Erkana.github.io/Awesome_Book/)
76 |
77 | (back to top )
78 |
79 |
80 |
81 |
82 | ## 💻 Getting Started
83 |
84 | - Create a local directory that you want to clone the repository.
85 |
86 | - Open the command prompt in the created directory.
87 |
88 | - On the terminal run this command git clone https://github.com/Lucas-Erkana/Awesome_Book.git
89 |
90 | - Go to the repository folder using command prompt cd Awesome_Book.
91 |
92 | - Install the dev dependencies for linters run npm install.
93 |
94 | (back to top )
95 |
96 | ### Prerequisites
97 |
98 | In order to run this project you need:
99 |
100 | -Google chrome
101 |
102 | -Internet Explorer
103 |
104 | -Any broswer
105 |
106 |
107 | (back to top )
108 |
109 | ### Setup
110 |
111 | Clone this repository to your desired folder:
112 |
113 | - Open the command prompt in the created directory.
114 |
115 | - On the terminal run this command git clone https://github.com/Lucas-Erkana/Awesome_Book.git
116 |
117 | - Go to the repository folder using command prompt cd LucasErkanaPortfolio_Website.
118 |
119 | - Install the dev dependencies for linters run npm install.
120 | --->
121 |
122 |
123 | (back to top )
124 |
125 |
126 |
127 | ## 👤**Authors**
128 | Lucas Erkana
129 |
130 | [githubhandle](https://github.com/Lucas-Erkana)
131 |
132 | [twitterhandle](https://twitter.com/@Lucas_David_22)
133 |
134 | [linkedIn](https://www.linkedin.com/in/lucas-erkana/)
135 |
136 | [facebook](https://www.facebook.com/lucash.toni)
137 |
138 | Kashif-Saleem-Ghuman
139 |
140 | [githubhandle](https://github.com/Kashif-Saleem-Ghuman)
141 |
142 | [linkedIn](https://www.linkedin.com/in/kashifsaleemghuman/)
143 |
144 |
145 |
146 | (back to top )
147 |
148 |
149 |
150 | ## 🔭 Future Features
151 |
152 | - Implement some UX improvements: add a home page, include transitions and/or animation
153 |
154 | - Implement additional pages, which will allow the user to Register
155 |
156 | - Implement additional pages, which will allow the user to Login
157 |
158 | (back to top )
159 |
160 |
161 |
162 | ## 🤝 Contributing
163 |
164 | Contributions, issues, and feature requests are welcome!
165 |
166 | Feel free to check the [issues page](https://github.com/Lucas-Erkana/Awesome_Book/issues/2).
167 |
168 | (back to top )
169 |
170 |
171 |
172 | ## ⭐️ Show your support
173 |
174 | Give a ⭐️ if you like this project!
175 |
176 | (back to top )
177 |
178 |
179 |
180 | ## 🙏 Acknowledgments
181 |
182 | [Font Awesome](https://fontawesome.com/search?q=book&o=r)
183 |
184 | [Icons8](https://icons8.com/icons/set/books)
185 |
186 | [Google Fonts](https://developers.google.com/fonts)
187 |
188 |
189 | [Bootsrtap](https://getbootstrap.com/docs/5.1/getting-started/introduction/)
190 |
191 |
192 | [Luxon](https://imdac.github.io/modules/js/luxon/)
193 |
194 |
195 | (back to top )
196 |
197 |
198 |
199 |
200 |
201 | ## 📝 License
202 |
203 | This project is [MIT](./LICENSE) licensed.
204 |
205 | _NOTE: we recommend using the [MIT license](https://choosealicense.com/licenses/mit/) - you can set it up quickly by [using templates available on GitHub](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository). You can also use [any other license](https://choosealicense.com/licenses/) if you wish._
206 |
207 | (back to top )
208 |
--------------------------------------------------------------------------------