diff --git a/.eslintrc.js b/.eslintrc.js index e69de29..ef46313 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -0,0 +1,62 @@ +module.exports = { + "env": { + "es6": true, + "node": true, + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "array-bracket-spacing": ["error", "never"], + "array-element-newline": ["error", "consistent"], + "arrow-spacing": ["error", { "before": true, "after": true }], + "block-spacing": "error", + "camelcase": 0, + "comma-spacing": ["error", { "before": false, "after": true }], + "computed-property-spacing": ["error", "never"], + "dot-location": ["error", "property"], + "eol-last": ["error", "always"], + "func-call-spacing": ["error", "never"], + "function-paren-newline": ["error", "never"], + "implicit-arrow-linebreak": ["error", "beside"], + "indent": ["error", 2, { "SwitchCase": 1 }], + "key-spacing": ["error", { "afterColon": true }], + "keyword-spacing": ["error", { "before": true, "after": true }], + "linebreak-style": ["error", "unix"], + "max-len": ["error", { "code": 120, "ignoreComments": true, "ignoreTrailingComments": true }], + "no-console": "error", + "no-case-declarations": 0, + "no-mixed-spaces-and-tabs": "error", + "no-multi-spaces": "error", + "no-spaced-func": "error", + "no-trailing-spaces": ["error", { "ignoreComments": true }], + "no-whitespace-before-property": "error", + "nonblock-statement-body-position": ["error", "beside"], + "object-curly-newline": ["error", { "multiline": true, "minProperties": 5, "consistent": true }], + "object-curly-spacing": ["error", "always", { "arraysInObjects": true, "objectsInObjects": true }], + "object-property-newline": ["error", { "allowAllPropertiesOnSameLine": true }], + "one-var": ["error", "never"], + "operator-linebreak": ["error", "after", { "overrides": { "?": "before", ":": "before" } }], + "padded-blocks": ["error", "never"], + "padding-line-between-statements": [ + "error", + { blankLine: "always", prev: "*", next: "return" }, + { blankLine: "always", prev: ["const", "let", "var"], next: "*" }, + { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"] }, + ], + "quotes": ["error", "single"], + "rest-spread-spacing": ["error", "never"], + "space-before-blocks": "error", + "space-before-function-paren": ["error", { "anonymous": "always", "named": "never", "asyncArrow": "always" }], + "space-in-parens": ["error", "never"], + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": ["error", "always"], + "semi": ["error", "never"], + "semi-spacing": ["error", { "before": false, "after": true }], + "switch-colon-spacing": "error", + "template-tag-spacing": ["error", "always"], + } +}; \ No newline at end of file diff --git a/.pug-lintrc.js b/.pug-lintrc.js new file mode 100644 index 0000000..5ae7099 --- /dev/null +++ b/.pug-lintrc.js @@ -0,0 +1,24 @@ +module.exports = { + disallowAttributeConcatenation: true, + disallowBlockExpansion: true, + disallowClassLiterals: true, + disallowDuplicateAttributes: true, + disallowHtmlText: true, + disallowIdLiterals: true, + disallowLegacyMixinCall: true, + disallowMultipleLineBreaks: true, + disallowSpacesInsideAttributeBrackets: true, + disallowStringConcatenation: 'aggressive', + disallowTagInterpolation: true, + disallowTrailingSpaces: true, + requireLineFeedAtFileEnd: true, + requireLowerCaseAttributes: true, + requireLowerCaseTags: true, + requireSpaceAfterCodeOperator: true, + requireStrictEqualityOperators: true, + validateAttributeQuoteMarks: '"', + validateExtensions: true, + validateIndentation: 2, + validateLineBreaks: 'LF', + validateTemplateString: true +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..ac6034b --- /dev/null +++ b/index.js @@ -0,0 +1,18 @@ +const express = require('express') + +const app = express() + +app.set('view engine', 'pug') +app.use(express.static('public')) + +app.get('/', (request, response) => { + return response.status(200).render('index') +}) + +app.all('*', (request, response) => { + return response.status(404).send('Looks like you found nothing in the pokedex.') +}) + +app.listen(1337, () => { + console.log('Listening on 1337...')// eslint-disable-line no-console +}) diff --git a/package.json b/package.json index 3e4bcde..d2850fa 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "main": ".eslintrc.js", "scripts": { "dev": "./node_modules/.bin/nodemon index.js", - "lint": "run lint:pug-lint && run lint:eslint", + "lint": "run lint:puglint && run lint:eslint", "lint:eslint": "./node_modules/.bin/eslint --format codeframe .", - "lint:puglint": "./node_modules/.bin/pug-lint ." + "lint:pug": "./node_modules/.bin/pug-lint ." }, "repository": { "type": "git", @@ -26,7 +26,6 @@ }, "dependencies": { "express": "^4.17.1", - "pug": "^2.0.4", - "s": "^1.0.0" + "pug": "^2.0.4" } } \ No newline at end of file diff --git a/public/css/styles.css b/public/css/styles.css new file mode 100644 index 0000000..7738eea --- /dev/null +++ b/public/css/styles.css @@ -0,0 +1,83 @@ +body{ + margin-top: 150px; +} + +h2{ + text-align: center; +} + +h3{ + margin-bottom: 5px; +} + +.delete{ + color: crimson; + font-weight: bold; +} + +.delete, .get, .post{ + padding-right: 10px; +} + +.get{ + color: green; + font-weight: bold; +} + +.hidden{ + display: none; +} + +.highlighted{ + background-color: lightgray; + position: relative; + width: 320px; +} + +.highlighted:after { + bottom: 0; + border-bottom: 15px solid transparent; + border-left: 15px solid lightgray; + border-top: 15px solid transparent; + content: ""; + position: absolute; + right: -15px; + width: 0; +} + +.left-container{ + margin: 0px 30px; + width: 320px; +} + +.main-container{ + display: flex; + flex-direction: row; + justify-content: center; +} + +.post{ + color: darkorange; + font-weight: bold; +} + +.right-container{ + margin: 0px 20px; + position: relative; + width: 440px; +} + +.spacing{ + margin: 20px 0px; + padding-left: 20px; +} + +.tabs{ + cursor: pointer; + font-size: 20px; + letter-spacing: 1px; + margin: 30px 0; + padding-top: 4px; + padding-left: 5px; + padding-bottom: 3px; +} diff --git a/public/javascripts/indexPugInteraction.js b/public/javascripts/indexPugInteraction.js new file mode 100644 index 0000000..d3ad3af --- /dev/null +++ b/public/javascripts/indexPugInteraction.js @@ -0,0 +1,18 @@ +/* eslint-disable no-undef */ +// eslint-disable-next-line no-unused-vars +const updateSelected = (id) => { + const tabs = document.getElementsByClassName('tabs') + const methods = document.getElementsByClassName('method') + + for (let i = 0; i < tabs.length; i++) { + tabs[i].id === id + ? tabs[i].classList.add('highlighted') + : tabs[i].classList.remove('highlighted') + } + + for (let i = 0; i < methods.length; i++) { + methods[i].id === id + ? methods[i].classList.remove('hidden') + : methods[i].classList.add('hidden') + } +} diff --git a/views/index.pug b/views/index.pug new file mode 100644 index 0000000..972ff05 --- /dev/null +++ b/views/index.pug @@ -0,0 +1,13 @@ +html + head + title Pokemon API + link(rel="stylesheet" href="/css/styles.css") + script(src="/javascripts/indexPugInteraction.js") + + body + h2 Welcome to the Pokemon API + div(class="main-container") + + include partials/leftSideDocumentation.pug + + include partials/rightSideDocumentaion.pug diff --git a/views/partials/leftSideDocumentation.pug b/views/partials/leftSideDocumentation.pug new file mode 100644 index 0000000..12c5c5c --- /dev/null +++ b/views/partials/leftSideDocumentation.pug @@ -0,0 +1,19 @@ +div(class="left-container") + div(class="tabs highlighted" id="getAll" onclick="updateSelected('getAll')") + span(class="get") GET + span /pokemon + div(class="tabs" id="getGeneration" onclick="updateSelected('getGeneration')") + span(class="get") GET + span /generation/{genId} + + div(class="tabs" id="getPokemonById" onclick="updateSelected('getPokemonById')") + span(class="get") GET + span /pokemon/{pokemonId} + + div(class="tabs" id="postPokemon" onclick="updateSelected('postPokemon')") + span(class="post") POST + span /pokemon + + div(class="tabs" id="deletePokemonById" onclick="updateSelected('deletePokemonById')") + span(class="delete") DELETE + span /pokemon/{pokemonId} diff --git a/views/partials/rightSideDocumentaion.pug b/views/partials/rightSideDocumentaion.pug new file mode 100644 index 0000000..0eb036c --- /dev/null +++ b/views/partials/rightSideDocumentaion.pug @@ -0,0 +1,52 @@ +div(class="right-container") + div(class="method" id="getAll") + h3 Method + div(class="get spacing") GET + h3 Route + div(class="spacing") http://localhost:1337/pokemon + h3 Headers + div(class="spacing") None needed + h3 Decription + div(class="spacing") Returns a list all of the pokemon in the databse. + + div(class="method hidden" id="getGeneration") + h3 Method + div(class="spacing get") GET + h3 Route + div(class="spacing") http://localhost:1337/pokemon/generations/{genId} + h3 Headers + div(class="spacing") None needed + h3 Decription + div(class="spacing") Returns the generation list of all pokemon associated with {genId}. + + div(class="method hidden" id="getPokemonById") + h3 Method + div(class="spacing get") GET + h3 Route + div(class="spacing") http://localhost:1337/pokemon/pokemon/{pokemonId} + h3 Headers + div(class="spacing") None needed + h3 Decription + div(class="spacing") Returns the pokemon associated with the {id} (Id's are also the pokemon's pokedex number). + + div(class="method hidden" id="postPokemon") + h3 Method + div(class="spacing post") POST + h3 Route + div(class="spacing") http://localhost:1337/pokemon + h3 Headers + div(class="spacing") Content-Type: application/json + h3 Body + div(class="spacing") { "gen": "1", "name": "Bulbasaur", "Types": "['grass', 'poison']" } + h3 Decription + div(class="spacing") Returns a list all of the pokemon in the databse. + + div(class="method hidden" id="deletePokemonById") + h3 Method + div(class="spacing delete") DELETE + h3 Route + div(class="spacing") http://localhost:1337/pokemon/pokemon/{pokemonId} + h3 Headers + div(class="spacing") None needed + h3 Decription + div(class="spacing") Deletes the pokemon associated with the {id} (Id's are also the pokemon's pokedex number).