Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cf108e1
Create index.html
jaycribas May 16, 2017
1a6b549
Merge pull request #1 from jaycribas/html
jaycribas May 16, 2017
31d27c2
add ajax requests to api
jnware7 May 16, 2017
2528cbf
Merge pull request #2 from jaycribas/script.js
jaycribas May 16, 2017
2a08425
add css styling
jaycribas May 16, 2017
b3cc91a
add header image
jaycribas May 16, 2017
a3c2119
Merge pull request #3 from jaycribas/styling
jaycribas May 16, 2017
1eb3d23
Update README with specs
jaycribas May 16, 2017
e37b6d3
Update README with team
jaycribas May 16, 2017
dda9193
Merge pull request #4 from jaycribas/contract
jaycribas May 16, 2017
338665b
Update README.md
jaycribas May 16, 2017
226eada
fix link to speakers image
jaycribas May 16, 2017
1827920
Merge pull request #5 from jaycribas/speakers
jaycribas May 16, 2017
24598ca
add nodemon to dependencies
jaycribas May 16, 2017
2b22c26
remove nodemon startup, change to node
jaycribas May 16, 2017
2eeb15f
edit paths
jaycribas May 16, 2017
6e53e0c
edit paths
jaycribas May 16, 2017
426b7cc
edit paths
jaycribas May 16, 2017
1ea90aa
change http to https
jaycribas May 16, 2017
9c40bbd
Implement media query to hide caption div
jaycribas May 16, 2017
2ccb62f
Merge pull request #6 from jaycribas/hide-genres
jnware7 May 16, 2017
a2c4422
Update README.md
jaycribas May 16, 2017
aa2015e
Add release date, tilt album titles, fix hide caption on resize
jaycribas May 18, 2017
3c32986
Merge pull request #7 from jaycribas/release-date
jnware7 May 18, 2017
57662e6
add button and input field
jnware7 May 18, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 65 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,69 @@
# Mutably Starter Project
For goal #383
# CRUD Mutably #383
[good--music.herokuapp.com](https://good--music.herokuapp.com/)

## To get this project running
1. `npm install`
1. `npm start` to run (uses nodemon)

Team name: #befitting-penguin
Team: Jeffrey Ware, Jay Cribas

## Challenge Rating

This goal will likely be within your ZPD if you...

- Can build basic web sites with HTML & CSS
- Can add behavior to a web site with JavaScript
- Are familiar with DOM manipulation
- Are interested in making more complex interactive web pages

## Description

[Mutably](http://mutably.herokuapp.com/) is a mutable, RESTful, CRUD API. This means that it has endpoints that you can interact with RESTfully via a front-end.

Visit the repo page for information about the resources available and how to interact with them: [https://github.com/GuildCrafts/mutably](https://github.com/GuildCrafts/mutably)

Your goal is to build a front-end that consumes the Mutably API. You can choose any one of the 3 resources. You front-end needs to complete all of the CRUD (Create, Read, Update, Delete) functions.

For the goal, you will start with [this scaffolded template](https://github.com/GuildCrafts/mutably-starter). Fork to get started.
You will use jQuery to complete this goal.

## Context

Interacting with a third-party API is a key skill for any developer. Most APIs have extensive documentation and require a fair amount of "overhead" just to get started working with them.

Not Mutably. This API is _way_ simpler, with just a few _endpoints_ handling a few different _resources_.

This goal is designed as an introduction to working with third-party APIs so that you can familiarize yourself with the core ideas before moving on to work with bigger, more complex APIs (like GitHub or Twitter).

## Specifications

- [x] __5:__ Your repo is a fork of [mutably-starter](https://github.com/GuildCrafts/mutably-starter).
- [x] __5:__ Your repo has a README with instructions for how to run your project.
- [x] __15:__ Your app is SPA (single page app). All CRUD actions take place on the same page, preferably the root (`/`) route.
- [x] __10:__ All interaction with the API happens with jQuery's AJAX function -- don't submit data via forms. You can use `form` html tags, but do all your form submission in your `js`. Make use of jQuery's `event.preventDefault()`.
- [x] __15:__ A user can read and display all the data for a resource.
- [x] __10:__ A user can create a new item via a create form. When the user creates a new item, that item should either get appended to the page or all the items should get re-retrieved in the `js`. No full page refresh.
- [x] __10:__ A user can update an existing item. Updating happens inline. This means that there is an edit button next to each item that, when clicked, the item text gets replaced with an pre-populated editable, input field. And the edit button becomes a save button. Once the save button is clicked and success message comes back from the server, then then input gets replaced with the updated text. No page refresh.
For example, this: <br>
<img width="229" alt="screen shot 2017-05-11 at 3 26 09 pm" src="https://cloud.githubusercontent.com/assets/3010270/25974508/4ac57980-365e-11e7-8b1f-6cf9eefaac22.png">
<br>
becomes:
<br>
<img width="253" alt="screen shot 2017-05-11 at 3 26 18 pm" src="https://cloud.githubusercontent.com/assets/3010270/25974512/5024433e-365e-11e7-802f-c60afacddecd.png">
<br>
When the user clickes the edit button.
- [x] __10:__ A user can delete an existing item via a delete button next to each item. No page refresh.
- [x] __10:__ Use a UI library to make your site look nice.
- [x] __5:__ The artifact produced is properly licensed, preferably with the MIT license.
- [x] __5:__ App is deployed on Heroku.

### Stretch

- [ ] Create another version of your front-end using a front-end framework such as React or Angular.

---

***If the mutably data gets too crazy from people adding / deleting things, you can reset the data to the seed data [here](http://mutably.herokuapp.com/).***

***Insider tip: there is an example "solution" (remember, there are MANY ways to hack it!) in the [solution branch](https://github.com/GuildCrafts/mutably-starter/tree/solution) of the starter template.***
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "",
"main": "server.js",
"scripts": {
"start": "nodemon server.js",
"start": "node server.js",
"start:dev": "nodemon server",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
Expand Down
Binary file added public/images/speakers.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<title>Mutably front-end</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/style.css">
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script type="text/javascript" src="script.js"></script>
<link href="https://fonts.googleapis.com/css?family=Shadows+Into+Light" rel="stylesheet">
</head>
<body class="container">
<div class="jumbotron">
<h1>GOOD MUSIC</h1>
<p class='shadows'>You only need 6 albums to win.</p>
</div>
<div class="col-sm-12">
<form class="form-inline well" id="new-album-form">
<div class="form-group">
<label for="title">Album Name</label>
<input type="text" class="form-control" name="name" id="name" placeholder="Album name">
</div>
<div class="form-group">
<label for="author">Artist</label>
<input type="text" class="form-control" name="artistName" id="artistName" placeholder="Artist">
</div>
<div class="form-group">
<label for="genres">Genre</label>
<input type="text" class="form-control" name="genres" id="genres" placeholder="Genres">
</div>
<div class="form-group">
<label for="releaseDate">ReleaseDate</label>
<input type="text" class="form-control" name="releaseDate" id="releaseDate" placeholder="releaseDate">
</div>
<div class="buttonDiv">
<button class= "addAlbum"type="submit">Add album</button>
</div>
</form>

<div class="panel panel-default">
<div class="panel-heading shadows">ALBUMS</div>
<div class="row">

</div>
</div>
</div>
</body>
</html>
98 changes: 96 additions & 2 deletions public/script.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,101 @@
console.log("Sanity Check: JS is working!");
console.log("GOOD MUSIC is live!");

$(document).ready(function(){

// code in here
// get all the data on load of the page
getAllalbums();

$('#new-album-form').on('submit', function(event) {
event.preventDefault()
var newAlbumData = $(this).serialize();
console.log(newAlbumData);
$(this).trigger("reset");
$.ajax({
method: 'POST',
url: 'https://mutably.herokuapp.com/albums/',
data: newAlbumData,
success: handleAlbumAddResponse
})
})

// becasue the delete-btn is added dynamically, the click handler needs to be written like such, bound to the document
$(document).on('click', '.delete-btn', function() {
var id = $(this).data('id')
$.ajax({
method: 'DELETE',
url: 'https://mutably.herokuapp.com/albums/'+id,
success: handleAlbumDeleteResponse
})
})

$(document).on('click', '.edit-btn', function() {
var id = $(this).data('id')

// hide the static name, show the input field
$('.name-'+id).hide()
$('.input-'+id).show()

// hide the edit button, show the save button
$('.edit-'+id).hide()
$('.save-'+id).show()

})

$(document).on('click', '.save-btn', function() {
var id = $(this).data('id')

// grab the user's inputted data
var updatedname = $('.input-'+id+' input').val()
$.ajax({
method: 'PUT',
url: 'https://mutably.herokuapp.com/albums/'+id,
data: {name: updatedname},
success: handleAlbumUpdateResponse
})
})
});

function getAllalbums() {
$('.row').html('')
$.ajax({
method: 'GET',
url: 'https://mutably.herokuapp.com/albums'
}).done(function(data) {
for (var i=0; i<data.albums.length; i++) {
$('.row').append('<div class="col-sm-4 col-md-2-'+data.albums[i]._id+'">'
+'<div class="thumbnail"><h3><span class="center-name name-'+data.albums[i]._id+'">'+data.albums[i].name+'</span></h3>'
+'<span class="form-inline edit-form input-'+data.albums[i]._id+'">&nbsp;<input class="form-control" value="'+data.albums[i].name+'"/></span>'
+'<img src="https://f4.bcbits.com/img/0001215340_10.jpg" alt="..."><div class="caption"><h6>'+data.albums[i].releaseDate+'</p><h4>'+data.albums[i].artistName+'</h4><p class="shadows">'+data.albums[i].genres+'</h6></div>'
+'<button class="btn btn-primary edit-btn edit-'+data.albums[i]._id+'" data-id="'+data.albums[i]._id+'">Edit</button>'
+'<button class="btn btn-success save-btn save-'+data.albums[i]._id+'" data-id="'+data.albums[i]._id+'">Save</button>'
+'<button class="btn btn-danger delete-btn pull-right" data-id="'+data.albums[i]._id+'">Delete</button>')
}
})
}


function handleAlbumAddResponse(data) {
console.log(data);
// reretrieve and rerender all the albums
getAllalbums();
}

function handleAlbumDeleteResponse(data) {
console.log('handleAlbumDeleteResponse got ', data);
var albumId = data._id;
var $row = $('.col-md-2-' + albumId);
// remove that album row
$row.remove();
}

function handleAlbumUpdateResponse(data) {
var id = data._id;

// replace the old name with the new name
$('.name-'+id).html('&nbsp;'+data.name)

$('.name-'+id).show()
$('.input-'+id).hide()
$('.edit-'+id).show()
$('.save-'+id).hide()
}
128 changes: 127 additions & 1 deletion public/style.css
Original file line number Diff line number Diff line change
@@ -1 +1,127 @@
/*Custom styles here*/

.row {
padding: 1%;
}

.jumbo {
font-size: 2em;
}

.jumbotron {
background-image: url('/images/speakers.jpg');
background-size: 100% auto;
background-position: center;
color: white;
text-shadow: 2px 2px 9px #000000;
}
.buttonDiv{
display:inline-block;
padding-left: 30px;
}
.addAlbum{
border-radius: 7px;
width:120px;
height: 30px;
color:white;
border:none;
}
.edit-form {
display: none;
}

.save-btn {
display: none;
position: absolute;
margin-top: 20px;
bottom: 40px;
border: 0px;
}

h3 {
color: white;
text-shadow: 2px 2px 9px #000000;
padding: 0 3%;
-ms-transform: rotate(-7deg); /* IE 9 */
-webkit-transform: rotate(-7deg); /* Chrome, Safari, Opera */
transform: rotate(-7deg);
font-size: 2vw;
}

h4 {
margin: 0;
}

h6 {
margin: 0;
font-size: .8em;
text-align: right;
font-weight: normal;
}

h6:before {
display: block;
white-space: pre;
content: 'Release Date\A';
}

input {
font-family: 'Shadows Into Light', cursive;
letter-spacing: .1em;
}

.shadows {
font-family: 'Shadows Into Light', cursive;
letter-spacing: .1em;
}

span {
position: absolute;
display: flex;
z-index: 2;
height: 60px;
margin-top: 70px;
}

.thumbnail {
height: 500px;
}

.edit-btn {
position: absolute;
margin-top: 20px;
bottom: 40px;
background-color: black;
border: 0px;
}

.edit-btn:hover {
background-color: #1f1f1f;
}

.delete-btn {
margin-left: 50px;
position: absolute;
margin-top: 20px;
bottom: 40px;
border: 0px;
}

h1, h3 {
font-family: 'Lato', sans-serif;
font-weight: 900;
text-transform: uppercase;
}


@media only screen
and (max-width: 768px) {
.row {
padding: 0;
}
div.caption {
display: none;
}
h3 {
font-size: 10vw;
}
}
2 changes: 1 addition & 1 deletion server.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ app.engine('html', ejs.renderFile);
app.set('view engine', 'html');

app.get('/', (request, response) => {
response.render('index')
response.sendFile('./public/index.html')
})

const port = process.env.PORT || 3000
Expand Down
23 changes: 0 additions & 23 deletions views/index.html

This file was deleted.