├── .gitignore ├── README.md ├── app ├── LICENSE.md ├── app.js ├── package.json └── public │ ├── index.html │ ├── style.css │ └── tweet.js └── node-exercises ├── basic └── app.js ├── cheer-jeer └── app.js ├── express └── app.js ├── params └── app.js ├── posting ├── app.js ├── package.json └── public │ ├── index.html │ └── posting.js └── static-assets ├── app.js ├── npm-debug.log └── public ├── index.html ├── kitties.js └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules/** -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Updated Course Released 2 | 3 | 🔥 There is an updated version of this course available here: [Complete Intro to Web Development, v2](https://frontendmasters.com/courses/web-development-v2/) 4 | 5 | # Intro to Web Dev App 6 | 7 | This app is the accompanying app the first Intro to Web Dev class taught by [@btholt](https://github.com/btholt) and [@nnja](https://github.com/nnja) for [Frontend Masters](http://www.frontendmasters.com). 8 | 9 | The slides to accompany this presentation you may find [here](https://docs.google.com/presentation/d/1KeWOWSM28qYI1mtkuHkY2vB2UUhwNkg7sq_LPqfYXKs/edit?usp=sharing). 10 | 11 | The course videos are here: [Introduction to Web Development](https://frontendmasters.com/courses/web-development/). 12 | 13 | It is a very basic Twitter clone using node.js and jQuery. 14 | 15 | ## Organization 16 | The main app is in the app folder. A bunch of smaller exercises are in the node-exercises folder. Make sure you run `npm install` in each folder that has a `package.json`. 17 | 18 | ## Contributing 19 | 20 | Feel free to fork and make pull requests if you see any mistakes or better ways to instruct students. 21 | 22 | ## License 23 | 24 | For any code we've written, it is free to use, abuse, and shape any way you see fit under the MIT license. 25 | -------------------------------------------------------------------------------- /app/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Brian Holt 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /app/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | var bodyParser = require('body-parser') 4 | app.use(bodyParser.json()); 5 | 6 | 7 | var tweets = [ 8 | {text: "Hai dude.", time: new Date().getTime() - 12300}, 9 | {text: "This is cool.", time: new Date().getTime() - 1000}, 10 | {text: "What's up?", time: new Date().getTime()}, 11 | ]; 12 | 13 | app.use(express.static(__dirname + '/public')); 14 | 15 | app.get('/ajax', function(request, response) { 16 | response.type('json'); 17 | response.end(JSON.stringify({tweets:tweets})); 18 | }); 19 | 20 | app.post('/ajax', function(request, response) { 21 | var newTweet = {text: request.body.tweet, time: new Date().getTime()}; 22 | tweets.push(newTweet); 23 | response.type('json'); 24 | response.end(JSON.stringify(newTweet)); 25 | }); 26 | 27 | var server = app.listen(8080); -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "intro-to-webdev-app", 3 | "version": "0.0.0", 4 | "description": "Intro to Web Dev app for Frontend Masters", 5 | "main": "app.js", 6 | "author": "Brian Holt ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "express": "~4.6.0", 10 | "body-parser": "~1.4.3" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tweeter 6 | 7 | 8 | 9 | 10 | 11 |

Tweeter

12 | 13 |
14 | 15 | 16 |
17 | 18 |
19 | 20 |
21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/public/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | width: 100%; 7 | font-family: 'Open Sans', sans-serif; 8 | color: #333; 9 | margin: 0; 10 | } 11 | 12 | .leader-h { 13 | width: 100%; 14 | background-color: #333; 15 | color: #fafafa; 16 | padding: 50px 10%; 17 | margin: 0; 18 | } 19 | 20 | .tweet-container { 21 | margin: 20px auto; 22 | width: 80%; 23 | padding: 30px; 24 | border: 2px solid gray; 25 | border-radius: 10px; 26 | overflow: hidden; 27 | } 28 | 29 | .new-tweet-input { 30 | width: 100%; 31 | height: 32px; 32 | border: 2px solid lightgray; 33 | border-radius: 5px; 34 | padding-left: 5px; 35 | } 36 | 37 | .new-tweet-input:focus { 38 | border-color: #00cccc; 39 | outline: none; 40 | } 41 | 42 | .btn-tweet { 43 | margin-top: 10px; 44 | background-color: #33cc00; 45 | color: #fafafa; 46 | font-size: 16px; 47 | float: right; 48 | border: none; 49 | padding: 7px 14px; 50 | border-radius: 5px; 51 | cursor: pointer; 52 | } 53 | 54 | .btn-tweet:hover { 55 | background-color: #4DE61A; 56 | } 57 | 58 | .btn-tweet:active { 59 | background-color: #009900; 60 | } 61 | 62 | .tweet-time { 63 | color: gray; 64 | font-style: italic; 65 | margin-bottom: 10px; 66 | font-size: 12px; 67 | } 68 | 69 | .tweet-body { 70 | font-size: 20px; 71 | } -------------------------------------------------------------------------------- /app/public/tweet.js: -------------------------------------------------------------------------------- 1 | $.ajax({ 2 | type: "GET", 3 | url:"/ajax", 4 | success: function(data) { 5 | for (var i = 0; i < data.tweets.length; i++) { 6 | appendNewTweet(data.tweets[i]); 7 | } 8 | } 9 | }); 10 | 11 | function appendNewTweet(tweet) { 12 | var newTweet = "
" + 13 | "
" + new Date(tweet.time).toLocaleString() + "
" + 14 | "
" + tweet.text + "
" + 15 | "
"; 16 | 17 | $('#tweets-target').prepend(newTweet); 18 | } 19 | 20 | $('#tweet').click(function() { 21 | $.ajax({ 22 | type: "POST", 23 | url: "/ajax", 24 | contentType: 'application/json', 25 | data: JSON.stringify({tweet: $('#new-tweet').val()}), 26 | success: function(data) { 27 | appendNewTweet(data); 28 | $('#new-tweet').val(''); 29 | } 30 | }) 31 | }); -------------------------------------------------------------------------------- /node-exercises/basic/app.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | http.createServer(function (req, res) { 3 | res.writeHead(200, {'Content-Type': 'text/plain'}); 4 | res.end('Hello World\n'); 5 | }).listen(8080, '127.0.0.1'); 6 | console.log('Server running at http://127.0.0.1:8080/'); -------------------------------------------------------------------------------- /node-exercises/cheer-jeer/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | 4 | app.get('/cheer.txt', function(req, res){ 5 | res.send("That shirt doesn't look awful on you."); 6 | }); 7 | 8 | app.get('/jeer.txt', function(req, res){ 9 | res.send("I'm pretty sure your scent is unpleasant."); 10 | }); 11 | 12 | var server = app.listen(8080); -------------------------------------------------------------------------------- /node-exercises/express/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | 4 | app.get('/hello.txt', function(req, res){ 5 | res.send('Hello World'); 6 | }); 7 | 8 | var server = app.listen(8080, function() { 9 | console.log('Listening on port 8080'); 10 | }); -------------------------------------------------------------------------------- /node-exercises/params/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | 4 | app.get('/team/:name', function(req, res){ 5 | res.setHeader('Content-Type','text/plain'); 6 | res.send("You picked " + req.params.name); 7 | }); 8 | 9 | var server = app.listen(8080); -------------------------------------------------------------------------------- /node-exercises/posting/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | var bodyParser = require('body-parser') 4 | app.use(bodyParser.json()); 5 | 6 | app.use(express.static(__dirname + '/public')); 7 | 8 | app.post('/login', function(req, res){ 9 | console.log(req.body.username + " " + req.body.password); 10 | if (req.body.username === "brian" && req.body.password === "pass") { 11 | res.json(200, {status:"success"}); 12 | } 13 | else { 14 | res.json(401, {status:"failure"}) 15 | } 16 | }); 17 | 18 | var server = app.listen(8080); -------------------------------------------------------------------------------- /node-exercises/posting/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "posting", 3 | "version": "0.0.0", 4 | "description": "Posting cool data to the server", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Brian Holt ", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "~4.6.1", 13 | "body-parser": "~1.5.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /node-exercises/posting/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Posting 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /node-exercises/posting/public/posting.js: -------------------------------------------------------------------------------- 1 | $('#submit-btn').click(function() { 2 | $.ajax({ 3 | type: "POST", 4 | url: "login", 5 | contentType: "application/json", 6 | data: JSON.stringify({ 7 | username: $("#username").val(), 8 | password: $("#password").val() 9 | }), 10 | success: function(data) { 11 | console.log('data', data); 12 | } 13 | }) 14 | }); -------------------------------------------------------------------------------- /node-exercises/static-assets/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | 4 | app.use(express.static(__dirname + '/public')); 5 | 6 | var server = app.listen(8080); -------------------------------------------------------------------------------- /node-exercises/static-assets/npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ '/Users/brian/.nvm/v0.10.24/bin/node', 3 | 1 verbose cli '/Users/brian/.nvm/v0.10.24/bin/npm', 4 | 1 verbose cli 'install' ] 5 | 2 info using npm@1.3.21 6 | 3 info using node@v0.10.24 7 | 4 error install Couldn't read dependencies 8 | 5 error package.json ENOENT, open '/Users/brian/talks/intro-to-webdev-app/node-exercises/static-assets/package.json' 9 | 5 error package.json This is most likely not a problem with npm itself. 10 | 5 error package.json npm can't find a package.json file in your current directory. 11 | 6 error System Darwin 13.3.0 12 | 7 error command "/Users/brian/.nvm/v0.10.24/bin/node" "/Users/brian/.nvm/v0.10.24/bin/npm" "install" 13 | 8 error cwd /Users/brian/talks/intro-to-webdev-app/node-exercises/static-assets 14 | 9 error node -v v0.10.24 15 | 10 error npm -v 1.3.21 16 | 11 error path /Users/brian/talks/intro-to-webdev-app/node-exercises/static-assets/package.json 17 | 12 error code ENOPACKAGEJSON 18 | 13 error errno 34 19 | 14 verbose exit [ 34, true ] 20 | -------------------------------------------------------------------------------- /node-exercises/static-assets/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | node.js! 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /node-exercises/static-assets/public/kitties.js: -------------------------------------------------------------------------------- 1 | $('button').click(function() { 2 | var x = Math.round(Math.random() * 500); 3 | var y = Math.round(Math.random() * 500); 4 | $('div').append(''); 5 | }); -------------------------------------------------------------------------------- /node-exercises/static-assets/public/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | font-size: 50px; 3 | background-color: pink; 4 | border: 2px solid transparent; 5 | } 6 | 7 | img { 8 | float:left; 9 | } --------------------------------------------------------------------------------