├── .hintrc
├── webpack.config.js
├── .eslintrc.json
├── .stylelintrc.json
├── LICENSE
├── package.json
├── src
├── index.html
├── index.js
└── style.css
├── .gitignore
├── .github
└── workflows
│ └── linter.yml
└── README.md
/.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 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved:0 */
2 | const path = require('path');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 |
5 | module.exports = {
6 | module: {
7 | rules: [
8 | {
9 | test: /\.css$/,
10 | use: ['style-loader', 'css-loader'],
11 | },
12 | ],
13 | },
14 | plugins: [
15 | new HtmlWebpackPlugin({
16 | template: path.resolve(__dirname, 'src', 'index.html'),
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 | "eol-last": "off",
17 | "import/extensions": [
18 | 1,
19 | {
20 | "js": "always",
21 | "json": "always"
22 | }
23 | ]
24 | },
25 | "ignorePatterns": ["dist/", "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": [
6 | true,
7 | {
8 | "ignoreAtRules": [
9 | "tailwind",
10 | "apply",
11 | "variants",
12 | "responsive",
13 | "screen"
14 | ]
15 | }
16 | ],
17 | "scss/at-rule-no-unknown": [
18 | true,
19 | {
20 | "ignoreAtRules": [
21 | "tailwind",
22 | "apply",
23 | "variants",
24 | "responsive",
25 | "screen"
26 | ]
27 | }
28 | ],
29 | "csstree/validator": true
30 | },
31 | "ignoreFiles": [
32 | "build/**",
33 | "dist/**",
34 | "**/reset*.css",
35 | "**/bootstrap*.css",
36 | "**/*.js",
37 | "**/*.jsx"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Nahom_zd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "leaderboard",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "webpack --mode development",
9 | "start": "webpack serve --mode development --open"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/zdnahom/leaderboard.git"
14 | },
15 | "keywords": [],
16 | "author": "",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/zdnahom/leaderboard/issues"
20 | },
21 | "homepage": "https://github.com/zdnahom/leaderboard#readme",
22 | "devDependencies": {
23 | "babel-eslint": "^10.1.0",
24 | "css-loader": "^6.7.3",
25 | "eslint": "^7.32.0",
26 | "eslint-config-airbnb-base": "^14.2.1",
27 | "eslint-plugin-import": "^2.27.5",
28 | "html-webpack-plugin": "^5.5.0",
29 | "style-loader": "^3.3.1",
30 | "stylelint": "^13.13.1",
31 | "stylelint-config-standard": "^21.0.0",
32 | "stylelint-csstree-validator": "^1.9.0",
33 | "stylelint-scss": "^3.21.0",
34 | "webpack": "^5.75.0",
35 | "webpack-cli": "^5.0.1",
36 | "webpack-dev-server": "^4.11.1"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 | Leaderboard Homepage
14 |
15 |
16 |
19 |
20 |
21 |
22 | Recent scores
23 | Refresh
24 |
25 |
26 |
27 | User
28 | Score
29 |
30 |
31 |
32 |
33 | Add your score
34 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars: 0 */
2 | import './style.css';
3 |
4 | const refreshButton = document.querySelector('.recent-scores button');
5 | const leaders = document.querySelector('.leaders');
6 | const form = document.querySelector('form');
7 | const successElement = document.querySelector('form span');
8 |
9 | const { name, score } = form.elements;
10 |
11 | const generateScores = (data) => {
12 | data.forEach((item) => {
13 | const player = document.createElement('div');
14 | player.innerHTML = `
15 | ${item.user} ${item.score}
16 | `;
17 | leaders.appendChild(player);
18 | });
19 | };
20 |
21 | const createNewGame = async () => {
22 | await fetch(
23 | 'https://us-central1-js-capstone-backend.cloudfunctions.net/api/games/',
24 | {
25 | method: 'POST',
26 | body: JSON.stringify({
27 | name: "Beat Nahom's score",
28 | }),
29 | headers: {
30 | 'Content-type': 'application/json; charset=UTF-8',
31 | },
32 | },
33 | );
34 | };
35 |
36 | const refreshBoard = async () => {
37 | const res = await fetch('https://us-central1-js-capstone-backend.cloudfunctions.net/api/games/BwlgxYvt8p5JJSu0N3Ht/scores');
38 | const data = await res.json();
39 | const { result } = data;
40 |
41 | result.sort((a, b) => {
42 | if (Number(a.score) > Number(b.score)) {
43 | return -1;
44 | }
45 | if (Number(a.score) > Number(b.score)) {
46 | return 1;
47 | }
48 | return 0;
49 | });
50 |
51 | generateScores(result);
52 | };
53 |
54 | const addScore = async (userName, score) => {
55 | await fetch(
56 | 'https://us-central1-js-capstone-backend.cloudfunctions.net/api/games/BwlgxYvt8p5JJSu0N3Ht/scores',
57 | {
58 | method: 'POST',
59 | body: JSON.stringify({
60 | user: userName,
61 | score,
62 | }),
63 | headers: {
64 | 'Content-type': 'application/json; charset=UTF-8',
65 | },
66 | },
67 | );
68 | };
69 | refreshButton.addEventListener('click', () => {
70 | leaders.innerHTML = '';
71 | refreshBoard();
72 | });
73 |
74 | form.addEventListener('submit', (event) => {
75 | event.preventDefault();
76 | addScore(name.value, score.value);
77 | name.value = '';
78 | score.value = '';
79 | successElement.textContent = 'Successfully added score to the game!';
80 | });
81 | window.addEventListener('DOMContentLoaded', () => {
82 | refreshBoard();
83 | });
84 |
--------------------------------------------------------------------------------
/.github/workflows/linter.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 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700;900&display=swap");
2 | @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
3 |
4 | * {
5 | margin: 0;
6 | padding: 0;
7 | box-sizing: border-box;
8 | font-family: 'Press Start 2P', cursive;
9 | }
10 |
11 | body {
12 | background-image: url('https://cdna.artstation.com/p/assets/images/images/047/517/388/original/inkpendude-portal-storm.gif?1647794887');
13 | background-size: cover;
14 | height: 100vh;
15 | padding: 0;
16 | margin: 0;
17 | }
18 |
19 | .btn {
20 | background-color: #f8cb01;
21 | border-radius: 0.5rem;
22 | border: 1px solid #ffe260;
23 | color: #fff;
24 | line-height: 1.5em;
25 | letter-spacing: 0.03em;
26 | transition-duration: 0.4s;
27 | padding: 5px 10px;
28 | cursor: pointer;
29 | }
30 |
31 | .btn:hover {
32 | transform: scale(1.2);
33 | }
34 |
35 | header {
36 | padding-top: 50px;
37 | padding-left: 2%;
38 | }
39 |
40 | header h1 {
41 | font-size: 4em;
42 | color: #fff;
43 | }
44 |
45 | main {
46 | padding: 35px 10%;
47 | display: flex;
48 | flex-direction: column;
49 | gap: 50px;
50 | }
51 |
52 | .leaderboard-section {
53 | width: 100%;
54 | }
55 |
56 | .recent-scores {
57 | display: flex;
58 | justify-content: space-between;
59 | }
60 |
61 | .recent-scores h2 {
62 | font-size: 1.5em;
63 | color: #fff;
64 | }
65 |
66 | .recent-scores button {
67 | align-self: center;
68 | }
69 |
70 | .leaders {
71 | display: flex;
72 | flex-direction: column;
73 | gap: 5px;
74 | border: 2px solid #f5e9b4;
75 | margin-top: 30px;
76 | max-height: 500px;
77 | overflow-y: scroll;
78 | -ms-overflow-style: none;
79 | scrollbar-width: none;
80 | }
81 |
82 | /* Hide scrollbar for Chrome, Safari and Opera */
83 | .leaders::-webkit-scrollbar {
84 | display: none;
85 | }
86 |
87 | .leaders div {
88 | display: flex;
89 | justify-content: space-between;
90 | padding: 10px;
91 | align-items: center;
92 | width: 100%;
93 | }
94 |
95 | .leaders div:nth-child(odd) {
96 | background-color: #f5e9b4;
97 | }
98 |
99 | .leaders div:nth-child(even) {
100 | background-color: white;
101 | }
102 |
103 | .leaders div:nth-child(1) {
104 | background-color: rgb(108, 247, 108);
105 | }
106 |
107 | .add-score {
108 | width: 80%;
109 | }
110 |
111 | .add-score h2 {
112 | font-size: 1.5em;
113 | color: #fff;
114 | }
115 |
116 | .add-score form {
117 | margin-top: 30px;
118 | display: flex;
119 | flex-direction: column;
120 | width: 100%;
121 | row-gap: 20px;
122 | }
123 |
124 | .add-score button {
125 | align-self: flex-end;
126 | }
127 |
128 | .add-score span {
129 | color: rgb(108, 247, 108);
130 | font-size: 1em;
131 | }
132 |
133 | .add-score input {
134 | padding: 8px;
135 | outline: none;
136 | }
137 |
138 | @media screen and (min-width: 768px) {
139 | main {
140 | display: flex;
141 | flex-direction: row;
142 | gap: 10%;
143 | }
144 |
145 | .leaderboard-section {
146 | width: 50%;
147 | }
148 |
149 | .add-score {
150 | width: 30%;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 📗 Table of Contents
4 |
5 | - [📗 Table of Contents](#-table-of-contents)
6 | - [📖 Leaderboard](#-leaderboard)
7 | - [🛠 Built With ](#-built-with-)
8 | - [Tech Stack ](#tech-stack-)
9 | - [Key Features ](#key-features-)
10 | - [🚀 Live Demo ](#-live-demo-)
11 | - [💻 Getting Started ](#-getting-started-)
12 | - [Prerequisites](#prerequisites)
13 | - [Setup](#setup)
14 | - [Install](#install)
15 | - [Usage](#usage)
16 | - [Run tests](#run-tests)
17 | - [👥 Authors ](#-authors-)
18 | - [🔭 Future Features ](#-future-features-)
19 | - [🤝 Contributing ](#-contributing-)
20 | - [⭐️ Show your support ](#️-show-your-support-)
21 | - [🙏 Acknowledgments ](#-acknowledgments-)
22 | - [❓ FAQ (OPTIONAL) ](#-faq-optional-)
23 | - [📝 License ](#-license-)
24 |
25 |
26 |
27 | # 📖 Leaderboard
28 | >
29 | Leaderboard is website which displays scores submitted by different players. It also allows you to submit your score. All data is preserved thanks to the external Leaderboard API service. It is built using pure javascript(ES6) , HTML, CSS, and Webpack.
30 |
31 | ## 🛠 Built With
32 |
33 | ### Tech Stack
34 |
35 |
36 | Client
37 |
42 |
43 |
44 | Server
45 |
49 |
50 |
51 |
52 |
53 |
54 | ### Key Features
55 |
56 | - **Display raw leaderboard data**
57 |
58 |
59 |
60 |
61 | (back to top )
62 |
63 |
64 |
65 | ## 🚀 Live Demo
66 |
67 | No live demo for now.But it will be added in the near future.
68 |
69 | (back to top )
70 |
71 |
72 | ## 💻 Getting Started
73 |
74 |
75 | ### Prerequisites
76 |
77 | In order to run this project you need: Configure your code editor with HTML , CSS & JS and some other important extensions
78 |
79 |
80 |
81 | ### Setup
82 |
83 | git clone git@github.com:zdnahom/leaderboard.git
84 |
85 |
86 |
87 | ### Install
88 |
89 | Install this project with:
90 |
91 | git clone git@github.com:zdnahom/leaderboard.git
92 |
93 |
94 | ### Usage
95 |
96 | To run the project, execute the following command:
97 | - cd leaderboard
98 | - npm install
99 | - npm run build
100 | - npm start
101 |
102 | ### Run tests
103 |
104 | No test module for now.But it will be added in the near future.
105 |
106 |
107 |
108 |
109 | ## 👥 Authors
110 |
111 | 👤 **Nahom Zerihun Demissie 💻**
112 | - GitHub: [@zdnahom](https://github.com/zdnahom/)
113 |
114 |
115 | (back to top )
116 |
117 |
118 |
119 | ## 🔭 Future Features
120 |
121 | - **Fetch data from Leaderboard API**
122 | - **Display players scores dynamically**
123 | - **Add player name and score**
124 | - **Sort players scores**
125 |
126 |
127 |
128 |
129 |
130 | (back to top )
131 |
132 |
133 |
134 | ## 🤝 Contributing
135 |
136 | Contributions, issues, and feature requests are welcome!
137 |
138 | Feel free to check the [issues page](../../issues/).
139 |
140 | (back to top )
141 |
142 |
143 |
144 | ## ⭐️ Show your support
145 |
146 | If you like this project , please clone it and try it . I know you're going to love it
147 |
148 | (back to top )
149 |
150 |
151 |
152 | ## 🙏 Acknowledgments
153 | I would like to thank Microverse(staffs , mentors , reviewers) giving me the knowledge to build an amazing project like this.
154 |
155 | (back to top )
156 |
157 |
158 |
159 | ## ❓ FAQ (OPTIONAL)
160 |
161 | - **Can I fork the project and make a contribution?**
162 |
163 | Of course you can! First fork it and contribute to it.
164 |
165 | - **How should I ask a pull request**
166 |
167 | - Step 1 : Click on the pull request button
168 | - Step 2 : create pull request
169 |
170 | (back to top )
171 |
172 |
173 |
174 | ## 📝 License
175 |
176 | This project is [MIT](./LICENSE) licensed.
177 |
178 | _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._
179 |
180 | (back to top )
181 |
--------------------------------------------------------------------------------