diff --git a/.gitignore b/.gitignore index cf709889..43be9456 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ **/node_modules +.DS_Store +public/.DS_Store +package-lock.json diff --git a/README.md b/README.md index 63387dea..f17778d6 100644 --- a/README.md +++ b/README.md @@ -1,151 +1,22 @@ -# Personal API +# Bird API -It's time to have some fun and play with the technologies you've learned in the past week. Your goal is to build a API about yourself. Your API will incorporate: -* Well-documented **JSON API** Endpoints -* A full set of **REST-ful Routes** (GET, POST, UPDATE, DELETE) -* At least one **CRUD-able resource** (Create, Read, Update, Destroy) -* and an `/api/profile` endpoint with some basic **details about you** +Welcome to the 'My Bird API'. You can use it to create and maintain your bird informations like: +* bird name +* bird type +* comments you want to add about the bird +* two images you can add for each bird +* a url link to learn more about this particular bird -Finally, you will **consume your API** using AJAX and **render the results** to the page using jQuery. You must complete *both* of these portions of the assignment. +## Technologies Used +* bootstrap for styling the HTML page +* ajax to send asynchronous HTTP request to server +* express and body-parser to provide the access to the server services +* Mongo DB and mongoose are used for noSQL DB -Please fork & clone this repo to get started. +See more API endpoint information [here](https://dry-scrubland-21249.herokuapp.com/api) -## Part 0. Deploy to Heroku -Before we start coding, our first goal together is to configure our application so that it can be deployed to Heroku (a web application host). +Some information about myself [Apichai](https://dry-scrubland-21249.herokuapp.com/api/profile) -Follow the instructions here: [Deploying Express Apps to Heroku](https://github.com/SF-WDI-LABS/shared_modules/blob/master/how-to/heroku-mean-stack-deploy.md) - -As you continue to work on this project, you'll need to remember to push your changes to heroku (just like you would with github!): - -```bash -# git add . -A -# git commit -m "detailed description of what I changed" -git push heroku master -heroku open -``` - -It's common for code to break "in production" (broken links, different environment, missing dependenies...), even if it worked in development, so do your best to debug! Let us know if you get stuck. - -## Part 1. Personal API -Now that we're deployed, it's time to start coding your "personal" api! - -#### Minimum Requirements - -- **Documented API Endpoints** - - - You must document your API endpoints. We really want to know *how* to use your API! And for starters, we need to know what endpoints exist! (Do this step first! _Plan plan plan!_) - - One cool way to do this is to create an endpoint at `/api` that describes all the available endpoints. We've set you up with an example in `server.js`. Make sure to update it to fill it in with your own information! - + Here's a good example student `/api` endpoint: - example api documentation - - + See the [Open API Initiative](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#paths-object-example) for what this looks like in practice. -- **A Profile Endpoint** (`/api/profile`) that responds with *hard-coded* data: - - + `name` - a string - + `githubUsername` - a string - + `githubLink` - a url to your github profile - + `githubProfileImage` - the url of your github profile image - + `personalSiteLink` - a link to your personal site. - + `currentCity` - + `pets` - an array of your pets - + e.g. `[{name: "foo", type: "Cat", breed: "Siamese"}, {name: "bar", type: "Dog", breed: "Dalmation"}]` - + if you do not have any pets, please get creative, or use hobbies instead - + Please hardcode it! It would be seriously overkill to save a single profile to the database. -- **At least one resource (mongoose model)** that you can _*CRUD*_ using _*RESTful Routes*_ - - That means endpoints for `index`, `show`, `create` `update`, `delete`! - - Here are some ideas: - * **RECOMMENDED:** `projects` that you have built for this class - - `_id`, name, description, githubRepoUrl, deployedUrl, screenshot - * `places` that you've lived or that are important to you - - `_id`, description, town, state, country, years, gps: {lat, lon}, photo - * `destinations` you've visited, or `vacations` you're planning - - `_id`, country, date, duration, photo - * `books` you've read or love - - `_id`, title, author, image, releaseDate, characters - * `movies` or `shows` you like - - `_id`, title, season, director - * `portfolioProjects` or `lyrics` you've written - - `_id`, title, body, date - * Wish list (e.g. `gifts` or `wishes`) - - `_id`, description, price, amazonLink - -All API Endpoints must return JSON. - - - -> **Pro-Tip**: One good strategy is to add the database *last*. Start with your api routes and some hard-coded data. Make sure it's working the way you want before tackling the database layer! - -#### API Stretch Goals -* Profile info stretch goals - * Add a `daysOld` field that calculates how many days old you are. - * Add an `isAwake` field that's only `true` between 8am and 10pm! -* CRUD resource stretch goals - * Use query parameters to filter results from one of your CRUD endpoints: - - e.g. `?limit=2` only return two results - * Create a `/search` endpoint - - e.g. `?q=mad+men` only returns tv shows with that in the title - - e.g. `?type=romance` only returns romance novels - -#### Examples -An example API for 'Jon Snow' might have endpoints like: - - JSON API Endpoint Response JSON - ============= ============= - GET /api/profile { - name: "Jon Snow", - githubLink: "http://github.com/u-know-nothing-jon-snow", - currentCity: "The Wall", - isAwake: false, - familyMembers: [ - { name: 'Arya Stark', relationship: 'sister' }, - { name: 'Bran Stark', relationship: 'brother' } - ] - } - - GET /api/projects [ - { - \_id: 2, - name: 'Defeat the wildlings', - type: 'quest', - opponents: [ 'Mance Rayder', 'Lord of Bones'], - status: 'resolved' - }, - { - \_id: 3, - name: 'Save the wildlings', - type: 'campaign', - opponents: ['the Night Watch', 'the Others'], - status: 'pending' - } - ] - - GET /api/projects?limit=1 [ { \_id: 2, name:'Defeat...' } ] - - GET /api/projects?status=pending - [ { \_id: 3, name:'Save...' } ] - GET /api/projects/2 { \_id: 2, name:'Defeat...' } - - POST /api/projects etc - PUT /api/projects/2 etc - DELETE /api/projects/2 etc - -Make sure to spend time planning this part out! - -## Part 2. Personal Dashboard - -#### Minimum Requirements -Consume the Personal API you just created, and use it to build your own personal dashboard. - -* Create an `index.html` **homepage** that's linked to your main JavaScript and CSS files. -* Use **jQuery** and **AJAX** to consume your Personal API. - -* Use **Template Strings** and **Array Iteration** to render data to the page. - -* Display **at least one image/gif** that you retrieved from your Personal API. -* Create **at least one form**, so you can CRUD at least one of your resources. -* Get rid of that ugly blue background. Style it up! - -
-
- - +## History +09/10/2017 - address Michelle's code review comments +09/01/2017 - initial creation diff --git a/controllers/birdsController.js b/controllers/birdsController.js new file mode 100644 index 00000000..d5b3eaf2 --- /dev/null +++ b/controllers/birdsController.js @@ -0,0 +1,79 @@ +//DB +const db = require("../models"); + +//GET /api/birds -- get all birds +function index(req, res) { + db.Bird.find({}, function(err, allBirds) { + if (err) { + console.log("Failed /api/birds "); + return; + } + res.json(allBirds); + }) +} + +//POST /api/birds -- adding a bird +function create(req, res) { + db.Bird.create(req.body, function(err, bird) { + console.log('entering db.Bird.create()'); + if (err) { + console.log(`create bird failed: err =${err}`); + return; + } + console.log("create bird success"); + res.json(bird); + }); +} + +function update(req, res) { + db.Bird.findById(req.params.birdId, function(err, bird){ + if (err) { + console.log(`Did not find bird id: ${req.params.birdId} in db`); + return; + } + + bird.name = req.body.name; + bird.type = req.body.type; + bird.comments = req.body.comments; + + bird.save(function(err, bird) { + if (err) { + console.log(`Failed to update bird id: ${bird._id} in db`); + return; + } + + res.json(bird); + }); + }); +} + +function destroy(req, res) { + db.Bird.findByIdAndRemove(req.params.birdId, function(err, bird) { + if (err) { + console.log(`Failed to delete bird id ${req.params.birdId}`); + return; + } + + res.json(bird); + }); +} + +function show(req, res) { + db.Bird.findById(req.params.birdId, function(err, bird) { + if (err) { + console.log(`Cannot find bird id ${req.params.birdId} in db`); + return; + } + + res.json(bird); + }); +} + +//public methods +module.exports = { + index: index, + create: create, + update: update, + destroy: destroy, + show: show, +} diff --git a/controllers/index.js b/controllers/index.js new file mode 100644 index 00000000..3a1c2e84 --- /dev/null +++ b/controllers/index.js @@ -0,0 +1,3 @@ +module.exports = { + birds: require("./birdsController"), +} diff --git a/models/bird.js b/models/bird.js new file mode 100644 index 00000000..c3e083b1 --- /dev/null +++ b/models/bird.js @@ -0,0 +1,27 @@ +// var mongoose = require('mongoose'), +// Schema = mongoose.Schema; + +// var CampsiteSchema = new Schema({ +// description: String +// }); + +// var Campsite = mongoose.model('Campsite', CampsiteSchema); + +// module.exports = Campsite; + +const mongoose = require("mongoose"); +const Schema = mongoose.Schema; + +let BirdSchema = new Schema({ + name: String, + type: String, + comments: String, + urlName: String, + url: String, + photo1: String, + photo2: String, +}); + +let Bird = mongoose.model('Bird', BirdSchema); + +module.exports = Bird; diff --git a/models/index.js b/models/index.js index 66997fe0..d0b8ae2c 100644 --- a/models/index.js +++ b/models/index.js @@ -3,3 +3,4 @@ mongoose.connect( process.env.MONGODB_URI || "mongodb://localhost/personal-api", mongoose.Promise = global.Promise; // use native Promise // module.exports.Campsite = require("./campsite.js.example"); +module.exports.Bird = require("./bird"); diff --git a/public/images/Crested-Caracara-89.jpg b/public/images/Crested-Caracara-89.jpg new file mode 100644 index 00000000..9efa30ee Binary files /dev/null and b/public/images/Crested-Caracara-89.jpg differ diff --git a/public/images/anhinga.jpeg b/public/images/anhinga.jpeg new file mode 100644 index 00000000..263e2424 Binary files /dev/null and b/public/images/anhinga.jpeg differ diff --git a/public/images/anhinga2.jpg b/public/images/anhinga2.jpg new file mode 100644 index 00000000..b3421ad3 Binary files /dev/null and b/public/images/anhinga2.jpg differ diff --git a/public/images/background12.jpeg b/public/images/background12.jpeg new file mode 100644 index 00000000..08471e39 Binary files /dev/null and b/public/images/background12.jpeg differ diff --git a/public/images/cara-inflight.jpg b/public/images/cara-inflight.jpg new file mode 100644 index 00000000..ca1cb6dc Binary files /dev/null and b/public/images/cara-inflight.jpg differ diff --git a/public/images/cara.jpg b/public/images/cara.jpg new file mode 100644 index 00000000..ed2b4181 Binary files /dev/null and b/public/images/cara.jpg differ diff --git a/public/images/gallinule.jpg b/public/images/gallinule.jpg new file mode 100644 index 00000000..982a2317 Binary files /dev/null and b/public/images/gallinule.jpg differ diff --git a/public/images/gallinule2.jpg b/public/images/gallinule2.jpg new file mode 100644 index 00000000..5128eabe Binary files /dev/null and b/public/images/gallinule2.jpg differ diff --git a/public/images/gallinule3.jpg b/public/images/gallinule3.jpg new file mode 100644 index 00000000..e61c930e Binary files /dev/null and b/public/images/gallinule3.jpg differ diff --git a/public/images/gallinule4.jpg b/public/images/gallinule4.jpg new file mode 100644 index 00000000..85139d3c Binary files /dev/null and b/public/images/gallinule4.jpg differ diff --git a/public/images/redtail-2.jpg b/public/images/redtail-2.jpg new file mode 100644 index 00000000..d51fd4b8 Binary files /dev/null and b/public/images/redtail-2.jpg differ diff --git a/public/images/redtail-inflight-2.jpg b/public/images/redtail-inflight-2.jpg new file mode 100644 index 00000000..92dfd90a Binary files /dev/null and b/public/images/redtail-inflight-2.jpg differ diff --git a/public/images/snail-kite-2.jpg b/public/images/snail-kite-2.jpg new file mode 100644 index 00000000..d86b75d8 Binary files /dev/null and b/public/images/snail-kite-2.jpg differ diff --git a/public/images/snail-kite.jpg b/public/images/snail-kite.jpg new file mode 100644 index 00000000..9ba34af2 Binary files /dev/null and b/public/images/snail-kite.jpg differ diff --git a/public/images/spoonbill3.jpg b/public/images/spoonbill3.jpg new file mode 100644 index 00000000..45aae022 Binary files /dev/null and b/public/images/spoonbill3.jpg differ diff --git a/public/images/spoonbill4.jpg b/public/images/spoonbill4.jpg new file mode 100644 index 00000000..e489a245 Binary files /dev/null and b/public/images/spoonbill4.jpg differ diff --git a/public/images/swaller-tailed-3.jpg b/public/images/swaller-tailed-3.jpg new file mode 100644 index 00000000..cc024762 Binary files /dev/null and b/public/images/swaller-tailed-3.jpg differ diff --git a/public/images/swallow-tailed-kite.jpg b/public/images/swallow-tailed-kite.jpg new file mode 100644 index 00000000..70f99131 Binary files /dev/null and b/public/images/swallow-tailed-kite.jpg differ diff --git a/public/images/swallow-tailed.jpg b/public/images/swallow-tailed.jpg new file mode 100644 index 00000000..6f48a4f9 Binary files /dev/null and b/public/images/swallow-tailed.jpg differ diff --git a/public/scripts/app.js b/public/scripts/app.js index 00988cd4..532de997 100644 --- a/public/scripts/app.js +++ b/public/scripts/app.js @@ -2,6 +2,171 @@ console.log("Sanity Check: JS is working!"); $(document).ready(function(){ -// your code - +//get all birds from db after the page reload +$.ajax({ + method: 'GET', + url: '/api/birds', +}) +.then(function(birds) { + if (birds.length !== 0) + renderAllBirds(birds); }); + +//adding a bird +$("#bird-form form").on("submit", handleAddBird); +//handling edit button click for editing a bird +$("#birds").on("click", ".edit-bird", handelEditBird); +//handling save button click for editing a bird +$("#birds").on("click", ".save-bird", handleSaveBird); +//handling delete button of a bird +$("#birds").on("click", ".delete-bird", handleDeleteBird); + +function renderAllBirds(birds) { + birds.forEach(renderBird); +} + +function renderBird(bird) { + console.log("entering renderBird()"); + + let htmlElem = ` +
+
+
+
+ +
+ +
+ +
+ +
+
    +
  • +

    Bird Name:

    + ${bird.name} +
  • + +
  • +

    Bird Type:

    + ${bird.type} +
  • + +
  • +

    Comments:

    + ${bird.comments} +
  • + +
  • +

    Learn more:

    + ${bird.urlName} +
  • +
+ +
+
+
+ + +
+ `; + + $("#birds").append(htmlElem); +} //function renderBird(bird) { + +function handleAddBird(e) { + e.preventDefault(); + console.log("app.js received submit button event"); + let birdData = $(this).serialize(); + console.log(`birdData: ${birdData}`); + + $.post("/api/birds", birdData, function(addedBird) { + console.log(`addedBird: ${addedBird}`); + renderBird(addedBird); + + $("[data-bird-id=" + addedBird._id + "]")[0].scrollIntoView(); + }); + $(this).trigger("reset"); +} + +function handelEditBird(e) { + e.preventDefault(); + let birdId = $(this).closest(".bird").data("bird-id"); + let $bird = $(this).closest(".bird"); + console.log(`handelEditBird: birdId = ${birdId}`); + + //toggle the save & edit button + $bird.find(".save-bird").toggleClass("hidden"); + $bird.find(".edit-bird").toggleClass("hidden"); + + //change the bird name in the span to become input with the value of the current bird name + let birdName = $bird.find(".bird-name").text(); + $bird.find(".bird-name").html(``); + + let birdType = $bird.find(".bird-type").text(); + $bird.find(".bird-type").html(``); + + let birdComments = $bird.find(".bird-comments").text(); + $bird.find(".bird-comments").html(``); + //now just wait for the usr to edit the above 3 inputs and click the save button that has class save-bird +} + +function handleSaveBird(e) { + e.preventDefault(); + + let birdId = $(this).closest(".bird").data("bird-id"); + let $bird = $(this).closest(".bird"); + + //toggle the save & edit button + $bird.find(".save-bird").toggleClass("hidden"); + $bird.find(".edit-bird").toggleClass("hidden"); + + let newBirdData = { + name: $bird.find(".edit-bird-name").val(), + type: $bird.find(".edit-bird-type").val(), + comments: $bird.find(".edit-bird-comments").val(), + }; + + console.log(`handleSaveBird() birdId = ${birdId}, newBirdData = ${newBirdData}`); + console.log(`url: /api/birds/${birdId}`); + + $.ajax({ + method: "PUT", + url: `/api/birds/${birdId}`, + data: newBirdData, + success: handleBirdUpdate, + }); +} + +function handleBirdUpdate(updatedBird) { + let birdId = updatedBird._id; + + //remove old bird item + $("[data-bird-id=" + birdId +"]").remove(); + renderBird(updatedBird); + + $("[data-bird-id=" + birdId + "]")[0].scrollIntoView(); +} + +function handleDeleteBird(e) { + e.preventDefault(); + + let $bird = $(this).closest(".bird"); + let birdId = $bird.data("bird-id"); + console.log(`handleDeleteBird(): deleting birdId ${birdId}`); + + $.ajax({ + method: "DELETE", + url: `/api/birds/${birdId}`, + success: function(deletedBird) { + $bird.remove(); + }, + }); +} + + +}); //$(document).ready(function(){ diff --git a/public/styles/styles.css b/public/styles/styles.css index 57b4da0e..ff363074 100644 --- a/public/styles/styles.css +++ b/public/styles/styles.css @@ -1,10 +1,73 @@ +/** { + border: 1px solid black; +}*/ + body { color: #333; font-family: Helvetica, Arial, sans-serif; - background-color: skyblue; /* Sanity Check! */ + background-image: url("../images/background12.jpeg"); + /*background-repeat: no-repeat;*/ + background-size: contain; } h1 { margin-top: 100px; text-align: center; } + +.bird { + margin: 3% 3%; + background-color: #ffd1b3; + border-width: thick; + border-style: ridge; + border-radius: 15px; +} + +.panel-footer { + background-color: #ffe0cc; +} +.image-container { + /*border-style: none;*/ + box-sizing: border-box; + padding: 1%; +} + +.image { + box-sizing: border-box; + border-width: medium; + border-style: ridge; + border-radius: 10px; + width: 100%; + height: 100%; +} + +.info-container { + box-sizing: border-box; + padding: 1%; +} + +.inline-header { + display: inline-block; + margin-right: 12px; + +} + +.list-group { + border-width: medium; + border-style: ridge; + border-radius: 10px; +} + +.list-group-item { + background-color: #ffe0cc; + /*opacity: 0.6;*/ + +} + +.list-group-item a { + margin: 0px 10px; +} + +.hidden { + display: none; +} diff --git a/seed.js b/seed.js index 896dead0..8ed15711 100644 --- a/seed.js +++ b/seed.js @@ -13,3 +13,99 @@ // console.log("Created new campsite", campsite._id) // process.exit(); // we're all done! Exit the program. // }) +const db = require("./models"); + +let birdSeed = [ + { + name: "Red Tail Hawk", + type: "bird of prey", + comments: "Very common. Often spotted circling search for prey. The field marks are the dark red color of the tail features, that's what all the books say. But for me, the dead give away is the dark band between shoulder and wrist seen in flight (as shown in the photo).", + urlName: "The Cornell Lab of Ornithology", + url: "https://www.allaboutbirds.org/guide/Red-tailed_Hawk/id", + // photo1: "images/red-tailed-hawk-1827949_960_720.jpg", + // photo2: "images/Red-Tailed Hawk In Flight.jpg", + photo1: "images/redtail-2.jpg", + photo2: "images/redtail-inflight-2.jpg" + }, + + { + name: "Crested Caracara", + type: "bird of prey", + comments: "Hard to find this majestic looking bird. I saw this only once in South Florida while driving in a back road.", + urlName: "whatbird.com", + url: "https://identify.whatbird.com/obj/56/overview/Crested_Caracara.aspx", + photo1: "images/cara.jpg", + photo2: "images/cara-inflight.jpg", + }, + + { + name: "Purple Gallinule", + type: "warm water marsh bird", + comments: "Very colorful. In the same family as Coots and Moorhen. An excellent wader.", + urlName: "Audubon", + url: "http://www.audubon.org/field-guide/bird/purple-gallinule", + photo1: "images/gallinule3.jpg", + photo2: "images/gallinule4.jpg", +}, + + { + name: "Snail Kite", + type: "bird of prey", + comments: "Snail is their only food source. Notice the curving beak for pulling out the snail from its shell. Resident of Florida only.", + urlName: "Audubon", + url: "http://fl.audubon.org/birds/everglade-snail-kite", + photo1: "images/snail-kite.jpg", + photo2: "images/snail-kite-2.jpg", + }, + + { + name: "Anhinga", + type: "water bird", + comments: "Tropical bird found in the southern swamps. They hunt by spear fishing. They have no fatty glands to repel water from their features so are often seen spreading their wings to dry out the features.", + urlName: "Animal Diversity Web", + url: "http://animaldiversity.org/accounts/Anhinga_anhinga/", + photo1: "images/anhinga.jpeg", + photo2: "images/anhinga2.jpg", + }, + + { + name: "Roseate Spoonbill", + type: "water bird", + comments: "These pretty birds feed in flocks around Gulf of Mexico and the Southwest. They swing their spoon-shaped bill back and forth in the water to catch small fish, crustaceans, and invertebrates.", + urlName: "Nature Works", + url: "http://www.nhptv.org/natureworks/roseatespoonbill.htm", + photo1: "images/spoonbill4.jpg", + photo2: "images/spoonbill3.jpg", + }, + + { + name: "Swallow-Tailed Kite", + type: "bird of prey", + comments: "Deeplyforked tail limited to Florida and surrounging area. I once saw a group of three flying over my head in the West Coast of Florida forrest. They rarely flapped their wings and flew by so gracefully.", + urlName: "Nature Works", + url: "https://abcbirds.org/bird/swallow-tailed-kite/", + photo1: "images/swallow-tailed-kite.jpg", + photo2: "images/swallow-tailed.jpg", + }, + +]; + +//wipe out everything in the db +db.Bird.remove({}, function(err, birds) { + if (err) { + console.log(`failed to remove all birds in db: err = ${err}`); + return; + } + + console.log("successfully wiped out everything in the db"); + + db.Bird.create(birdSeed, function(err, birds) { + if (err) { + console.log(`failed to create birdSeed: err = ${err}`); + return; + } + + console.log("successfully created birdSeed"); + process.exit(); //so it does not hang there + }); +}); diff --git a/server.js b/server.js index fd366289..8a6f3c3e 100644 --- a/server.js +++ b/server.js @@ -29,6 +29,7 @@ app.use(function(req, res, next) { // i.e. `/images`, `/scripts`, `/styles` app.use(express.static('public')); +let controllers = require('./controllers'); /* * HTML Endpoints */ @@ -37,24 +38,44 @@ app.get('/', function homepage(req, res) { res.sendFile(__dirname + '/views/index.html'); }); +app.get('/api/profile', function(req, res) { + res.json({ + name: "Apichai Chenthanakij(Chen)", + githubUserName: "achentha", + githubLink: "https://github.com/achentha", + githubProfileImage: "https://avatars2.githubusercontent.com/u/30161498?v=4&u=9f3d9d4479e61b9a8ed9ff4b8ca7440ec432ad54&s=400", + personalSiteLink: "https://dry-scrubland-21249.herokuapp.com/", + currentCity: "Fremont", + pets: [ + {name: "Angel Face", type: "Cat", breed: "Tabby"}, + {name: "Clutch", type: "Cat", breed: "Tabby"}, + ] + }); +}); + +app.get('/api/birds', controllers.birds.index); // get all birds +app.get('/api/birds/:birdId', controllers.birds.show); // get one bird +app.post('/api/birds', controllers.birds.create); // create a new bird +app.put('/api/birds/:birdId', controllers.birds.update); // edit a bird +app.delete('/api/birds/:birdId', controllers.birds.destroy); // delete a bird /* * JSON API Endpoints */ app.get('/api', function apiIndex(req, res) { - // TODO: Document all your api endpoints below as a simple hardcoded JSON object. - // It would be seriously overkill to save any of this to your database. - // But you should change almost every line of this response. res.json({ - woopsIForgotToDocumentAllMyEndpoints: true, // CHANGE ME ;) - message: "Welcome to my personal api! Here's what you need to know!", - documentationUrl: "https://github.com/example-username/express-personal-api/README.md", // CHANGE ME - baseUrl: "http://YOUR-APP-NAME.herokuapp.com", // CHANGE ME + message: "Welcome to my personal favorite birds api! Here's what you need to know!", + documentationUrl: "https://github.com/achentha/express-personal-api/blob/master/README.md", + baseUrl: "https://dry-scrubland-21249.herokuapp.com/", endpoints: [ {method: "GET", path: "/api", description: "Describes all available endpoints"}, - {method: "GET", path: "/api/profile", description: "Data about me"}, // CHANGE ME - {method: "POST", path: "/api/campsites", description: "E.g. Create a new campsite"} // CHANGE ME + {method: "GET", path: "/api/profile", description: "About me"}, + {method: "GET", path: "/api/birds", description: "Show all my favorite birds"}, + {method: "GET", path: "/api/birds/:birdId", description: "Show a specified favorite birds"}, + {method: "POST", path: "/api/birds", description: "Add a new favorite bird"}, + {method: "PUT", path: "/api/birds/:birdId", description: "Modify a favorite bird"}, + {method: "DELETE", path: "/api/birds/:birdId", description: "Delete a favorite bird"}, ] }) }); diff --git a/views/index.html b/views/index.html index 48e39ae6..d61e1b02 100644 --- a/views/index.html +++ b/views/index.html @@ -4,26 +4,113 @@ - Blank + My Favorite Birds - - + + - + + - + + + +
+
+
+
+
+ Add Bird + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+
+
+ + +
-

Under Construction

+

My Favorite Birds

Read My API Documentation

+ +
+
+
+

Birds

+
+
+ + +
+ +