├── .babelrc ├── .circleci └── config.yml ├── .editorconfig ├── .gitignore ├── README.md ├── app.json ├── build ├── controllers │ ├── DeveloperController.js │ └── DeveloperController.js.map ├── index.js ├── index.js.map ├── models │ ├── developers.js │ └── developers.js.map └── routes │ ├── index.js │ └── index.js.map ├── client ├── dist │ ├── bundle.min.js │ └── style.css ├── index.html ├── js │ ├── app.js │ ├── components │ │ ├── Developers.jsx │ │ ├── DevelopersList.js │ │ ├── Header.jsx │ │ └── Page.jsx │ └── tests │ │ └── App.test.js └── styles │ └── main.css ├── docs └── tutorials.md ├── package.json ├── server ├── controllers │ └── DeveloperController.js ├── index.js ├── models │ └── developers.js └── routes │ └── index.js ├── tests └── api.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { "presets": ["react", "es2015", "stage-2"] } 2 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/node:7.10 11 | 12 | # Specify service dependencies here if necessary 13 | # CircleCI maintains a library of pre-built images 14 | # documented at https://circleci.com/docs/2.0/circleci-images/ 15 | # - image: circleci/mongo:3.4.4 16 | 17 | working_directory: ~/repo 18 | 19 | steps: 20 | - checkout 21 | 22 | # Download and cache dependencies 23 | - restore_cache: 24 | keys: 25 | - v1-dependencies-{{ checksum "package.json" }} 26 | # fallback to using the latest cache if no exact match is found 27 | - v1-dependencies- 28 | 29 | - run: yarn install 30 | 31 | - save_cache: 32 | paths: 33 | - node_modules 34 | key: v1-dependencies-{{ checksum "package.json" }} 35 | 36 | # run tests! 37 | - run: yarn test 38 | machine: 39 | services: 40 | - mongodb 41 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | # EditorConfig is awesome: http://EditorConfig.org 4 | 5 | # top-most EditorConfig file 6 | root = true 7 | 8 | # Unix-style newlines with a newline ending every file 9 | [*] 10 | end_of_line = lf 11 | insert_final_newline = true 12 | 13 | # Matches multiple files with brace expansion notation 14 | # Set default charset 15 | [*.{js,html,css}] 16 | charset = utf-8 17 | 18 | # Tab indentation (no size specified) 19 | [Makefile] 20 | indent_style = tab 21 | 22 | # Indentation override for all JS under lib directory 23 | [**.js] 24 | indent_style = space 25 | indent_size = 2 26 | 27 | # Matches the exact files either package.json or .travis.yml 28 | [{package.json,.travis.yml}] 29 | indent_style = space 30 | indent_size = 2 31 | 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules 3 | .vscode 4 | .DS_Store 5 | package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PH Developers Directory 2 | [](https://circleci.com/gh/PHDevsConnect/phdevsdir/tree/master) 3 | 4 | 5 | A Directory app for web devs in Port Harcourt, Nigeria. Built with React, Express and MongoDB 6 | 7 | # API DOCS 8 | 9 | `GET` `https://phdevsdir.herokuapp.com/api/v1/developers` - display all developers 10 | `POST` `https://phdevsdir.herokuapp.com/api/v1/developers` - create a new developer 11 | Params 12 | 13 | - `first_name` (String) `required`, 14 | - `last_name` (String) `required` 15 | - `email` (String) `required` 16 | - `stack` (Comma Delimited String) `optional` 17 | - `github_url` (String) `required` 18 | 19 | # Using the API 20 | Here are some examples to aid in using the API. This API currently makes use of one endpoint (`/api/v1/developers`), with two HTTP verbs attached to it (GET & POST). 21 | 22 | ### JavaScript 23 | ```js 24 | 25 | // using XMLHttpRequest 26 | 27 | // GET 28 | let request = new XMLHttpRequest(); 29 | request.open('Get', "https://phdevsdir.herokuapp.com/api/v1/developers"); 30 | request.send(); 31 | 32 | request.onreadystatechange = (e) => { 33 | if(request.readyState == 4 && request.status == 200) { 34 | // request is successful, lets party 35 | let response = JSON.parse(request.responseText); 36 | console.log(response); 37 | } 38 | } 39 | 40 | // POST 41 | let request = new XMLHttpRequest(); 42 | request.open('POST', 'https://phdevsdir.herokuapp.com/api/v1/developers'); 43 | let params = 'params=value'; 44 | 45 | request.setRequestHeader('Content-Type', 'application/json'); // application/x-www-form-urlencoded, etc 46 | 47 | request.onreadystatechange = (e) => { 48 | if(request.readyState == 4 && request.status == 200) { 49 | let response = JSON.parse(request.responseText); 50 | console.log(response); 51 | } 52 | } 53 | request.send(params); 54 | 55 | // Using axios (its easy af!) 56 | axios.get('https://phdevsdir.herokuapp.com/api/v1/developers') 57 | .then( (response) => { 58 | console.log(response); 59 | }) 60 | .catch( (err) => { 61 | console.log(err); 62 | }); 63 | 64 | axios.post('https://phdevsdir.herokuapp.com/api/v1/developers', { 65 | first_name: 'John', 66 | second_name: 'Doe' 67 | }) 68 | .then( (response) => { 69 | console.log(response); 70 | }) 71 | .catch( (err) => { 72 | console.log(err); 73 | }); 74 | 75 | ``` 76 | ### PHP 77 | ```php 78 | send(); 83 | if ($r->getResponseCode() == 200) { 84 | $response = $r->getResponseBody(); 85 | } 86 | } catch (HttpException $ex) { 87 | echo $ex; 88 | } 89 | 90 | // POST 91 | $r = new HttpRequest('https://phdevsdir.herokuapp.com/api/v1/developers', HttpRequest::METH_POST); 92 | $r->addPostFields(['first_name' => 'john', 'last_name' => 'doe']); 93 | try { 94 | echo $r->send()->getBody(); 95 | } catch (HttpException $ex) { 96 | echo $ex; 97 | } 98 | ?> 99 | ``` 100 | ### Go 101 | ```go 102 | func main() { 103 | // GET 104 | request, err := http.Get("https://phdevsdir.herokuapp.com/api/v1/developers") 105 | if err != nil { 106 | log.Println(err) 107 | } 108 | 109 | defer request.Body.Close() 110 | 111 | requestBytes, err := ioutil.ReadAll(request.Body) 112 | if err != nil { 113 | log.Println(err) 114 | } 115 | response := string(bodyBytes) 116 | log.Print(response) 117 | 118 | // POST 119 | body := []bytes("firstname=john&lastname=doe") 120 | req, err := http.Post("https://phdevsdir.herokuapp.com/api/v1/developers", "body/type", bytes.NewBuffer(body)) 121 | 122 | if err != nil { 123 | log.Println(err) 124 | } 125 | defer req.Body.Close() 126 | bodyBytes, err := ioutil.ReadAll(res.Body) 127 | if err != nil { 128 | log.Println(err) 129 | } 130 | res := string(bodyBytes) 131 | } 132 | ``` 133 | ### Python 134 | ```python 135 | import requests 136 | import json 137 | 138 | // GET 139 | r = requests.get("https://phdevsdir.herokuapp.com/api/v1/developers") 140 | print r.content 141 | 142 | // POST 143 | url = "https://phdevsdir.herokuapp.com/api/v1/developers" 144 | payload = {'first_name': 'John', 'last_name': 'Doe'} 145 | response = requests.post(url, data=json.dumps(payload)) 146 | print(response.text) 147 | ``` 148 | 149 | # Contributing 150 | - Fork the repo 151 | - Make your changes 152 | - Create a PR 153 | - Create an Issue for feature requests 154 | 155 | # Using Postman to test routes 156 | - Install Postman (Google Chrome Required) https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en or Download the [Desktop Client](http://getpostman.com) 157 | - Launch the app from chrome://apps 158 | - Paste the app link in the url bar, set the request method (POST, GET, PUT, UPDATE, etc) 159 | - Hit "send" 160 | - New to POSTMAN? Check tuturials on docs/tutorials.md -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phdevsdir", 3 | "scripts": { 4 | }, 5 | "env": { 6 | "MONGODB_URI": { 7 | "required": true 8 | } 9 | }, 10 | "formation": { 11 | }, 12 | "addons": [ 13 | "mongolab" 14 | ], 15 | "buildpacks": [ 16 | { 17 | "url": "heroku/nodejs" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /build/controllers/DeveloperController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('mongoose'); 4 | var Developers = require('../models/developers'); 5 | 6 | exports.getDevelopers = function (req, res, next) { 7 | return Developers.find({}).exec(function (err, users) { 8 | if (err) { 9 | return res.status(500).send({ data: { error: err, status: 500, success: false } }); 10 | } else { 11 | return res.status(200).send({ data: { users: users, status: 200, success: true } }); 12 | } 13 | }); 14 | }; 15 | 16 | exports.newDeveloper = function (req, res, next) { 17 | var developerData = { 18 | first_name: req.body.first_name, 19 | last_name: req.body.last_name, 20 | email: req.body.email, 21 | stack: req.body.stack.split(',').map(function (elem) { 22 | return elem.trim(); 23 | }), 24 | github_url: req.body.github_url 25 | }; 26 | developers = new Developers(developerData).save().then(function () { 27 | return res.status(201).send({ data: { user: developerData, status: 201, success: true } }); 28 | }).catch(function (err) { 29 | console.log(err); 30 | return res.status(500).send({ data: { error: err, status: 500, success: false } }); 31 | }); 32 | }; 33 | //# sourceMappingURL=DeveloperController.js.map -------------------------------------------------------------------------------- /build/controllers/DeveloperController.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../server/controllers/DeveloperController.js"],"names":["mongoose","require","Developers","exports","getDevelopers","req","res","next","find","exec","err","users","status","send","data","error","success","newDeveloper","developerData","first_name","body","last_name","email","stack","split","map","elem","trim","github_url","developers","save","then","user","catch","console","log"],"mappings":";;AAAA,IAAMA,WAAWC,QAAQ,UAAR,CAAjB;AACA,IAAMC,aAAaD,QAAQ,sBAAR,CAAnB;;AAEAE,QAAQC,aAAR,GAAwB,UAACC,GAAD,EAAMC,GAAN,EAAWC,IAAX,EAAoB;AAC1C,SAAOL,WACJM,IADI,CACC,EADD,EAEJC,IAFI,CAEC,UAACC,GAAD,EAAMC,KAAN,EAAgB;AACpB,QAAID,GAAJ,EAAS;AACP,aAAOJ,IAAIM,MAAJ,CAAW,GAAX,EAAgBC,IAAhB,CAAqB,EAAEC,MAAM,EAAEC,OAAOL,GAAT,EAAcE,QAAQ,GAAtB,EAA2BI,SAAS,KAApC,EAAR,EAArB,CAAP;AACD,KAFD,MAEO;AACL,aAAOV,IAAIM,MAAJ,CAAW,GAAX,EAAgBC,IAAhB,CAAqB,EAAEC,MAAM,EAAEH,YAAF,EAASC,QAAQ,GAAjB,EAAsBI,SAAS,IAA/B,EAAR,EAArB,CAAP;AACD;AACF,GARI,CAAP;AASD,CAVD;;AAYAb,QAAQc,YAAR,GAAuB,UAACZ,GAAD,EAAMC,GAAN,EAAWC,IAAX,EAAoB;AACzC,MAAMW,gBAAgB;AACpBC,gBAAYd,IAAIe,IAAJ,CAASD,UADD;AAEpBE,eAAWhB,IAAIe,IAAJ,CAASC,SAFA;AAGpBC,WAAOjB,IAAIe,IAAJ,CAASE,KAHI;AAIpBC,WAAOlB,IAAIe,IAAJ,CAASG,KAAT,CAAeC,KAAf,CAAqB,GAArB,EAA0BC,GAA1B,CAA8B,UAACC,IAAD;AAAA,aAAUA,KAAKC,IAAL,EAAV;AAAA,KAA9B,CAJa;AAKpBC,gBAAYvB,IAAIe,IAAJ,CAASQ;AALD,GAAtB;AAOAC,eAAa,IAAI3B,UAAJ,CAAegB,aAAf,EAA8BY,IAA9B,GACZC,IADY,CACP,YAAM;AACV,WAAOzB,IAAIM,MAAJ,CAAW,GAAX,EAAgBC,IAAhB,CAAqB,EAAEC,MAAM,EAAEkB,MAAMd,aAAR,EAAuBN,QAAQ,GAA/B,EAAoCI,SAAS,IAA7C,EAAR,EAArB,CAAP;AACD,GAHY,EAGViB,KAHU,CAGJ,UAACvB,GAAD,EAAS;AAChBwB,YAAQC,GAAR,CAAYzB,GAAZ;AACA,WAAOJ,IAAIM,MAAJ,CAAW,GAAX,EAAgBC,IAAhB,CAAqB,EAAEC,MAAM,EAAEC,OAAOL,GAAT,EAAcE,QAAQ,GAAtB,EAA2BI,SAAS,KAApC,EAAR,EAArB,CAAP;AACD,GANY,CAAb;AAOD,CAfD","file":"DeveloperController.js","sourcesContent":["const mongoose = require('mongoose');\nconst Developers = require('../models/developers');\n\nexports.getDevelopers = (req, res, next) => {\n return Developers\n .find({})\n .exec((err, users) => {\n if (err) {\n return res.status(500).send({ data: { error: err, status: 500, success: false } });\n } else {\n return res.status(200).send({ data: { users, status: 200, success: true } });\n }\n });\n}\n\nexports.newDeveloper = (req, res, next) => {\n const developerData = {\n first_name: req.body.first_name,\n last_name: req.body.last_name,\n email: req.body.email,\n stack: req.body.stack.split(',').map((elem) => elem.trim()),\n github_url: req.body.github_url\n };\n developers = new Developers(developerData).save()\n .then(() => {\n return res.status(201).send({ data: { user: developerData, status: 201, success: true } });\n }).catch((err) => {\n console.log(err);\n return res.status(500).send({ data: { error: err, status: 500, success: false } });\n });\n}\n"]} -------------------------------------------------------------------------------- /build/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("babel-polyfill"); 4 | 5 | require("dotenv").config(); 6 | 7 | var express = require("express"), 8 | http = require("http"), 9 | socketio = require("socket.io"), 10 | router = express.Router(), 11 | helmet = require("helmet"), 12 | logger = require("morgan"), 13 | session = require("express-session"), 14 | cookieParser = require("cookie-parser"), 15 | bcrypt = require("bcrypt"), 16 | crypto = require("crypto"), 17 | path = require("path"), 18 | shortid = require("shortid"), 19 | fs = require("fs"), 20 | fileParser = require("connect-multiparty")(), 21 | validator = require("validator"), 22 | mime = require("mime"), 23 | bodyParser = require("body-parser"), 24 | mongoose = require("mongoose"), 25 | _ = require("lodash"), 26 | app = express(); 27 | 28 | var environment = process.env.NODE_ENV || "development"; 29 | mongoose.Promise = global.Promise; 30 | 31 | var online_DB_uri = "mongodb://heroku_8s9nbdfn:4vjc4tbv8oho7jg10tqnv1qd3p@ds113795.mlab.com:13795/heroku_8s9nbdfn", 32 | local_DB_uri = process.env.NODE_ENV === "test" ? "mongodb://codehakasee:codehakase1@ds121015.mlab.com:21015/phdevsdir-sb" : "mongodb://localhost:27017/phdevsdir"; 33 | 34 | mongoose.connect(environment === "production" ? online_DB_uri : local_DB_uri, { 35 | useMongoClient: true 36 | }, function (err, db) { 37 | if (err) { 38 | console.log("Couldn't connect to database"); 39 | } else { 40 | console.log("Connected To " + environment + " Database"); 41 | } 42 | }); 43 | 44 | app.use(logger("dev")); 45 | app.use(helmet()); 46 | app.disable("x-powered-by"); 47 | app.use(cookieParser()); 48 | app.use(bodyParser.json()); 49 | app.use(bodyParser.urlencoded({ extended: true })); 50 | process.env.PWD = process.cwd(); 51 | app.use(express.static(path.join(process.env.PWD, "public"))); 52 | 53 | var api = express.Router(); 54 | require("./routes/index.js")(api); 55 | app.get('/', function (req, res) { 56 | res.sendFile(path.join(__dirname, '../client/index.html')); 57 | }); 58 | app.get('/dist/*', function (req, res) { 59 | res.sendFile(path.join(__dirname, "../client/" + req.originalUrl)); 60 | }); 61 | app.use("/api/v1", api); 62 | app.get("/isAlive", function (req, res) { 63 | res.writeHead(200, { 'Content-Type': 'text/plain' }); 64 | res.end('Server is Up!\n'); 65 | }); 66 | 67 | /** 68 | * Serve API 69 | * Module dependencies. 70 | */ 71 | 72 | /** 73 | * Get port from environment and store in Express. 74 | */ 75 | 76 | var port = normalizePort(process.env.PORT || "3000"); 77 | app.set("port", port); 78 | 79 | /** 80 | * Create HTTP server. 81 | */ 82 | 83 | var server = http.createServer(app); 84 | var io = socketio(server); 85 | /** 86 | * Listen on provided port, on all network interfaces. 87 | */ 88 | 89 | server.listen(port, function () { 90 | console.log("listening on port " + port); 91 | }); 92 | server.on("error", onError); 93 | server.on("listening", onListening); 94 | 95 | /** 96 | * Normalize a port into a number, string, or false. 97 | */ 98 | 99 | function normalizePort(val) { 100 | var port = parseInt(val, 10); 101 | 102 | if (isNaN(port)) { 103 | // named pipe 104 | return val; 105 | } 106 | 107 | if (port >= 0) { 108 | // port number 109 | return port; 110 | } 111 | 112 | return false; 113 | } 114 | 115 | /** 116 | * Event listener for HTTP server "error" event. 117 | */ 118 | 119 | function onError(error) { 120 | if (error.syscall !== "listen") { 121 | throw error; 122 | } 123 | 124 | var bind = typeof port === "string" ? "Pipe " + port : "Port " + port; 125 | 126 | // handle specific listen errors with friendly messages 127 | switch (error.code) { 128 | case "EACCES": 129 | console.error(bind + " requires elevated privileges"); 130 | process.exit(1); 131 | break; 132 | case "EADDRINUSE": 133 | console.error(bind + " is already in use"); 134 | process.exit(1); 135 | break; 136 | default: 137 | throw error; 138 | } 139 | } 140 | 141 | /** 142 | * Event listener for HTTP server "listening" event. 143 | */ 144 | var debug = require("debug"); 145 | function onListening() { 146 | var addr = server.address(); 147 | var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port; 148 | debug("Listening on " + bind); 149 | } 150 | 151 | module.exports = app; // tests 152 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /build/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../server/index.js"],"names":["require","config","express","http","socketio","router","Router","helmet","logger","session","cookieParser","bcrypt","crypto","path","shortid","fs","fileParser","validator","mime","bodyParser","mongoose","_","app","environment","process","env","NODE_ENV","Promise","global","online_DB_uri","local_DB_uri","connect","useMongoClient","err","db","console","log","use","disable","json","urlencoded","extended","PWD","cwd","static","join","api","get","req","res","sendFile","__dirname","originalUrl","writeHead","end","port","normalizePort","PORT","set","server","createServer","io","listen","on","onError","onListening","val","parseInt","isNaN","error","syscall","bind","code","exit","debug","addr","address","module","exports"],"mappings":"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","file":"index.js","sourcesContent":["require(\"babel-polyfill\");\n\nrequire(\"dotenv\").config();\n\nconst express = require(\"express\"),\n http = require(\"http\"),\n socketio = require(\"socket.io\"),\n router = express.Router(),\n helmet = require(\"helmet\"),\n logger = require(\"morgan\"),\n session = require(\"express-session\"),\n cookieParser = require(\"cookie-parser\"),\n bcrypt = require(\"bcrypt\"),\n crypto = require(\"crypto\"),\n path = require(\"path\"),\n shortid = require(\"shortid\"),\n fs = require(\"fs\"),\n fileParser = require(\"connect-multiparty\")(),\n validator = require(\"validator\"),\n mime = require(\"mime\"),\n bodyParser = require(\"body-parser\"),\n mongoose = require(\"mongoose\"),\n _ = require(\"lodash\"),\n app = express();\n\nconst environment = process.env.NODE_ENV || \"development\";\nmongoose.Promise = global.Promise;\n\nconst online_DB_uri = `mongodb://heroku_8s9nbdfn:4vjc4tbv8oho7jg10tqnv1qd3p@ds113795.mlab.com:13795/heroku_8s9nbdfn`,\n local_DB_uri = (process.env.NODE_ENV === \"test\") ? \"mongodb://codehakasee:codehakase1@ds121015.mlab.com:21015/phdevsdir-sb\" : `mongodb://localhost:27017/phdevsdir`;\n\nmongoose.connect(\n environment === \"production\" ? online_DB_uri : local_DB_uri,\n {\n useMongoClient: true\n },\n (err, db) => {\n if (err) {\n console.log(\"Couldn't connect to database\");\n } else {\n console.log(`Connected To ${environment} Database`);\n }\n }\n);\n\napp.use(logger(\"dev\"));\napp.use(helmet());\napp.disable(\"x-powered-by\");\napp.use(cookieParser());\napp.use(bodyParser.json());\napp.use(bodyParser.urlencoded({ extended: true }));\nprocess.env.PWD = process.cwd();\napp.use(express.static(path.join(process.env.PWD, \"public\")));\n\nconst api = express.Router();\nrequire(\"./routes/index.js\")(api);\napp.get('/', (req, res) => {\n res.sendFile(path.join(__dirname, '../client/index.html'));\n});\napp.get('/dist/*', (req, res) => {\n res.sendFile(path.join(__dirname, `../client/${req.originalUrl}`));\n});\napp.use(\"/api/v1\", api);\napp.get(\"/isAlive\", (req, res) => {\n res.writeHead(200, {'Content-Type': 'text/plain'});\n res.end('Server is Up!\\n');\n});\n\n\n/**\n * Serve API\n * Module dependencies.\n */\n\n/**\n * Get port from environment and store in Express.\n */\n\nconst port = normalizePort(process.env.PORT || \"3000\");\napp.set(\"port\", port);\n\n/**\n * Create HTTP server.\n */\n\nconst server = http.createServer(app);\nconst io = socketio(server);\n/**\n * Listen on provided port, on all network interfaces.\n */\n\nserver.listen(port, function() {\n console.log(\"listening on port \" + port);\n});\nserver.on(\"error\", onError);\nserver.on(\"listening\", onListening);\n\n/**\n * Normalize a port into a number, string, or false.\n */\n\nfunction normalizePort(val) {\n const port = parseInt(val, 10);\n\n if (isNaN(port)) {\n // named pipe\n return val;\n }\n\n if (port >= 0) {\n // port number\n return port;\n }\n\n return false;\n}\n\n/**\n * Event listener for HTTP server \"error\" event.\n */\n\nfunction onError(error) {\n if (error.syscall !== \"listen\") {\n throw error;\n }\n\n const bind = typeof port === \"string\" ? \"Pipe \" + port : \"Port \" + port;\n\n // handle specific listen errors with friendly messages\n switch (error.code) {\n case \"EACCES\":\n console.error(bind + \" requires elevated privileges\");\n process.exit(1);\n break;\n case \"EADDRINUSE\":\n console.error(bind + \" is already in use\");\n process.exit(1);\n break;\n default:\n throw error;\n }\n}\n\n/**\n * Event listener for HTTP server \"listening\" event.\n */\nconst debug = require(\"debug\");\nfunction onListening() {\n const addr = server.address();\n const bind = typeof addr === \"string\" ? \"pipe \" + addr : \"port \" + addr.port;\n debug(\"Listening on \" + bind);\n}\n\nmodule.exports = app; // tests\n"]} -------------------------------------------------------------------------------- /build/models/developers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('mongoose'); 4 | var Schema = mongoose.Schema; 5 | 6 | var developersSchema = new Schema({ 7 | first_name: { 8 | type: String, 9 | required: true, 10 | trim: true 11 | }, 12 | last_name: { 13 | type: String, 14 | required: true, 15 | trim: true 16 | }, 17 | email: { 18 | type: String, 19 | required: true, 20 | trim: true, 21 | unique: true, 22 | lowercase: true 23 | }, 24 | stack: { 25 | type: Array, 26 | required: false 27 | }, 28 | github_url: { 29 | type: String, 30 | required: true, 31 | unique: true, 32 | lowercase: true 33 | }, 34 | created_at: { 35 | type: Date, 36 | required: false 37 | }, 38 | updated_at: { 39 | type: Number, 40 | required: false 41 | } 42 | }); 43 | 44 | var Developers = mongoose.model('Developers', developersSchema); 45 | 46 | module.exports = Developers; 47 | //# sourceMappingURL=developers.js.map -------------------------------------------------------------------------------- /build/models/developers.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../server/models/developers.js"],"names":["mongoose","require","Schema","developersSchema","first_name","type","String","required","trim","last_name","email","unique","lowercase","stack","Array","github_url","created_at","Date","updated_at","Number","Developers","model","module","exports"],"mappings":";;AAAA,IAAIA,WAAWC,QAAQ,UAAR,CAAf;AACA,IAAIC,SAASF,SAASE,MAAtB;;AAEA,IAAIC,mBAAmB,IAAID,MAAJ,CAAW;AAChCE,cAAY;AACVC,UAAMC,MADI;AAEVC,cAAU,IAFA;AAGVC,UAAM;AAHI,GADoB;AAMhCC,aAAW;AACTJ,UAAMC,MADG;AAETC,cAAU,IAFD;AAGTC,UAAM;AAHG,GANqB;AAWhCE,SAAO;AACLL,UAAMC,MADD;AAELC,cAAU,IAFL;AAGLC,UAAM,IAHD;AAILG,YAAQ,IAJH;AAKLC,eAAW;AALN,GAXyB;AAkBhCC,SAAO;AACLR,UAAMS,KADD;AAELP,cAAU;AAFL,GAlByB;AAsBhCQ,cAAY;AACVV,UAAMC,MADI;AAEVC,cAAU,IAFA;AAGVI,YAAQ,IAHE;AAIVC,eAAW;AAJD,GAtBoB;AA4BhCI,cAAY;AACVX,UAAMY,IADI;AAEVV,cAAU;AAFA,GA5BoB;AAgChCW,cAAY;AACVb,UAAMc,MADI;AAEVZ,cAAU;AAFA;AAhCoB,CAAX,CAAvB;;AAsCA,IAAIa,aAAapB,SAASqB,KAAT,CAAe,YAAf,EAA6BlB,gBAA7B,CAAjB;;AAEAmB,OAAOC,OAAP,GAAiBH,UAAjB","file":"developers.js","sourcesContent":["var mongoose = require('mongoose');\nvar Schema = mongoose.Schema;\n\nvar developersSchema = new Schema({\n first_name: {\n type: String,\n required: true,\n trim: true\n },\n last_name: {\n type: String,\n required: true,\n trim: true\n },\n email: {\n type: String,\n required: true,\n trim: true,\n unique: true,\n lowercase: true\n },\n stack: {\n type: Array,\n required: false\n },\n github_url: {\n type: String,\n required: true,\n unique: true,\n lowercase: true\n },\n created_at: {\n type: Date,\n required: false\n },\n updated_at: {\n type: Number,\n required: false\n }\n});\n\nvar Developers = mongoose.model('Developers', developersSchema);\n\nmodule.exports = Developers;"]} -------------------------------------------------------------------------------- /build/routes/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var DeveloperController = require('../controllers/DeveloperController'); 4 | 5 | var routes = function routes(app) { 6 | app.route('/developers').get(DeveloperController.getDevelopers).post(DeveloperController.newDeveloper); 7 | }; 8 | module.exports = routes; 9 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /build/routes/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../server/routes/index.js"],"names":["DeveloperController","require","routes","app","route","get","getDevelopers","post","newDeveloper","module","exports"],"mappings":";;AAAA,IAAMA,sBAAsBC,QAAQ,oCAAR,CAA5B;;AAEA,IAAMC,SAAS,SAATA,MAAS,CAACC,GAAD,EAAS;AACtBA,MAAIC,KAAJ,CAAU,aAAV,EACGC,GADH,CACOL,oBAAoBM,aAD3B,EAEGC,IAFH,CAEQP,oBAAoBQ,YAF5B;AAGD,CAJD;AAKAC,OAAOC,OAAP,GAAiBR,MAAjB","file":"index.js","sourcesContent":["const DeveloperController = require('../controllers/DeveloperController');\n\nconst routes = (app) => {\n app.route('/developers')\n .get(DeveloperController.getDevelopers)\n .post(DeveloperController.newDeveloper);\n}\nmodule.exports = routes;\n"]} -------------------------------------------------------------------------------- /client/dist/style.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | font-family: 'Source Sans Pro', sans-serif; 3 | margin: 0px; 4 | background-color: #ececec; 5 | } 6 | .developers { 7 | margin: 30px 100px; 8 | text-align: center; 9 | display: inline-block; 10 | } 11 | 12 | .developer { 13 | display: inline-block; 14 | box-shadow: 0px 0px 8px 1px #d4d1d1; 15 | border-radius: 3px; 16 | background-color: #fff; 17 | margin: 10px 0.5em; 18 | width: 250px; 19 | text-align: left; 20 | float: left; 21 | } 22 | 23 | .developer > .profile-pic > img { 24 | width: 100%; 25 | border-top-left-radius: 3px; 26 | border-top-right-radius: 3px; 27 | } 28 | 29 | .profile-data { 30 | padding: 20px; 31 | color: #454545; 32 | display: inline-block; 33 | bottom: 35px; 34 | box-sizing: border-box; 35 | padding-top: 5px; 36 | } 37 | 38 | .profile-data > span { 39 | display: inline-block; 40 | width: 100%; 41 | margin: 5px 0px; 42 | } 43 | 44 | .developer-name { 45 | font-size: 25px; 46 | height: 35px; 47 | width: 210px !important; 48 | text-overflow: ellipsis; 49 | white-space: nowrap; 50 | overflow: hidden; 51 | } 52 | 53 | .tech { 54 | padding: 5px; 55 | background-color: #2196F3; 56 | color: #fff; 57 | border-radius: 3px; 58 | font-size: 12px; 59 | margin-right: 5px; 60 | } 61 | 62 | .profile-data a { 63 | font-size: 12px; 64 | text-decoration: none; 65 | padding: 5px; 66 | background-color: #607D8B; 67 | color: #fff; 68 | margin-top: 10px; 69 | display: inline-block; 70 | border-radius: 3px; 71 | } 72 | 73 | .v-badge { 74 | font-size: 20px; 75 | font-weight: bolder; 76 | background-color: #E91E63; 77 | padding: 5px; 78 | border-radius: 50%; 79 | cursor: pointer; 80 | margin: 0px 5px; 81 | width: 25px; 82 | position: absolute; 83 | display: inline-block; 84 | box-shadow: 0px 0px 7px 1px rgba(19, 19, 19, 0.43); 85 | color: #ffffff; 86 | text-align: center; 87 | } 88 | 89 | .exp { 90 | font-size: 12px; 91 | display: inline; 92 | width: unset !important; 93 | padding: 5px; 94 | border-radius: 3px; 95 | background-color: #FF9800; 96 | box-shadow: 0px 0px 3px 1px rgba(128, 128, 128, 0.33); 97 | color: #fff; 98 | } 99 | 100 | .header { 101 | height: 50px; 102 | background-color: #2195f3; 103 | box-shadow: 0px 3px 10px 0px #bdbcbc; 104 | padding: 0px 7px; 105 | } 106 | 107 | .logo { 108 | display: inline-block; 109 | font-size: 30px; 110 | color: #fff; 111 | margin: 5px; 112 | } 113 | 114 | .search { 115 | display: inline-block; 116 | float: right; 117 | margin: 5px; 118 | padding: 5px; 119 | margin-right: 0px; 120 | } 121 | 122 | .search > input { 123 | padding: 10px; 124 | border-radius: 3px; 125 | border: none; 126 | } 127 | 128 | .profile-pic { 129 | height: 250px; 130 | } 131 | 132 | .badge-container { 133 | position: relative; 134 | bottom: 15px; 135 | left: 204px; 136 | } -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |