diff --git a/models/album.js b/models/album.js index 0411a57..ed4b236 100644 --- a/models/album.js +++ b/models/album.js @@ -1,2 +1,16 @@ var mongoose = require("mongoose"); var Schema = mongoose.Schema; + +var Song = require("./song"); + +var AlbumSchema = new Schema({ + artistName: String, + name: String, + releaseDate: String, + genres: [ String ], + songs: [ Song.schema] +}); + +var Album = mongoose.model('Album', AlbumSchema); + +module.exports = Album; \ No newline at end of file diff --git a/models/index.js b/models/index.js index 6c10401..8136df4 100644 --- a/models/index.js +++ b/models/index.js @@ -1,2 +1,6 @@ var mongoose = require("mongoose"); mongoose.connect("mongodb://localhost/tunely"); + +module.exports.Album = require("./album.js"); + +module.exports.Song = require("./song.js"); \ No newline at end of file diff --git a/models/song.js b/models/song.js new file mode 100644 index 0000000..3379e07 --- /dev/null +++ b/models/song.js @@ -0,0 +1,11 @@ +var mongoose = require("mongoose"); +var Schema = mongoose.Schema; + +var SongSchema = new Schema({ + name: String, + trackNumber: Number, +}); + +var Song = mongoose.model('Song', SongSchema); + +module.exports = Song; \ No newline at end of file diff --git a/package.json b/package.json index 0d3e4f8..6c11458 100644 --- a/package.json +++ b/package.json @@ -4,19 +4,26 @@ "description": "An app for tracking your music collection", "main": "server.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" }, "repository": { "type": "git", "url": "git+ssh://git@github.com/tgaff/tunely.git" }, "author": "tgaff", - "license": "ISC", + "license": "BSD-2-Clause", "bugs": { "url": "https://github.com/tgaff/tunely/issues" }, "homepage": "https://github.com/tgaff/tunely#readme", "dependencies": { - "express": "^4.13.3" + "express": "~4.13.3", + "mongoose": "~4.2.10", + "body-parser": "~1.14.1", + "mongodb": "~2.1.0" + }, + "directories": { + "doc": "docs" } } diff --git a/public/js/app.js b/public/js/app.js index 164eb55..1e85b41 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -5,88 +5,181 @@ * */ +$(document).ready(function() { + console.log('app.js loaded!'); -/* hard-coded data! */ -var sampleAlbums = []; -sampleAlbums.push({ - artistName: 'Ladyhawke', - name: 'Ladyhawke', - releaseDate: '2008, November 18', - genres: [ 'new wave', 'indie rock', 'synth pop' ] - }); -sampleAlbums.push({ - artistName: 'The Knife', - name: 'Silent Shout', - releaseDate: '2006, February 17', - genres: [ 'synth pop', 'electronica', 'experimental' ] - }); -sampleAlbums.push({ - artistName: 'Juno Reactor', - name: 'Shango', - releaseDate: '2000, October 9', - genres: [ 'electronic', 'goa trance', 'tribal house' ] - }); -sampleAlbums.push({ - artistName: 'Philip Wesley', - name: 'Dark Night of the Soul', - releaseDate: '2008, September 12', - genres: [ 'piano' ] - }); -/* end of hard-coded data */ +function getAndRenderAll() { + $.ajax({ + method: 'GET', + url: '/api/albums', + success: function (data) { + // console.log(data); + // data.albums.forEach( function ( element, index) { + // sampleAlbums.push(element); + // console.log(element); + // }); + // console.log(data); + + data.forEach( function ( element, index) { + var songs = ""; + element.songs.forEach ( function (element, index){ + var name = element.name; + songs = songs + (renderSong(element.name, element.trackNumber)); + }); + renderAlbum(element, songs); + // console.log(songs); + }); + + // {name: "Swamped", trackNumber: 1, _id: "56678bfd318047be62e12e66"} + + }, + error: function () { + console.log("uh oh..."); + } + }); +} +function renderSong(name, count) { + var songsHtml = +"
" + count + ". " + name + " "; + return songsHtml; +} +getAndRenderAll(); +// Form Input +//to create new design Project +var $addAlbum = $('.form-horizontal'); -$(document).ready(function() { - console.log('app.js loaded!'); +$addAlbum.on('submit', function (event) { + event.preventDefault(); + + // serialze form data + // var newAlbum = $(this).serialize(); + + var newAlbum = $(this).serialize(); + + // console.log(newAlbum); + + // POST request to create new designProject + $.post('/api/albums', newAlbum, function (data) { + console.log(data); + + // render all designProjects to view + getAndRenderAll(); + + }); + + // reset the form + $addAlbum[0].reset(); + $addAlbum.find('input').first().focus(); }); +//for adding new songs +$('#albums').on('click', '.add-song', function(e) { + var id = $(this).parents('.album').data('album-id'); + // console.log('id',id); + //adds the current album id data to the song modal + $('#songModal').data('album-id', id); + // console.log($('#songModal').data('album-id', id)); + //calls the song modal to add a song + $('#songModal').modal(); + $('#saveSong').on('click', handleNewSongSubmit() ,function() { + console.log('yes'); + }); +}); + + +// handles the modal fields and POSTing the form to the server +function handleNewSongSubmit(e) { + var albumId = $('#songModal').data('album-id'); + // console.log(albumId); + + var songName = $('#songName').val(); + var trackNumber = $('#trackNumber').val(); + + var formData = { + name: songName, + trackNumber: trackNumber + }; + + + var postUrl = '/api/albums/' + albumId + '/songs'; + console.log('posting to ', postUrl, ' with data ', formData); + + $.post(postUrl, formData) + .success(function(song) { + // console.log('song', song); + + // re-get full album and render on page + $.get('/api/albums/' + albumId).success(function(album) { + //remove old entry + $('[data-album-id='+ albumId + ']').remove(); + // render a replacement + getAndRenderAll(); + }); + + }); + + //clear form + $('#songName').val(''); + $('#trackNumber').val(''); + $('#songModal').modal('hide'); +} // this function takes a single album and renders it to the page -function renderAlbum(album) { - console.log('rendering album:', album); - - var albumHtml = - " " + - "
" + - "
" + - "
" + - "
" + - " " + - "
" + - "
" + - " album image" + - "
" + - "
" + - "
    " + - "
  • " + - "

    Album Name:

    " + - " " + "HARDCODED ALBUM NAME" + "" + - "
  • " + - "
  • " + - "

    Artist Name:

    " + - " " + "HARDCODED ARTIST NAME" + "" + - "
  • " + - "
  • " + - "

    Released date:

    " + - " " + "HARDCODED RELEASE DATE" + "" + - "
  • " + - "
" + - "
" + - "
" + - " " + - - "
" + // end of panel-body - - " " + - - "
" + - "
" + - " "; +function renderAlbum(album, songs) { + // console.log('rendering album:', album); + + var albumHtml = + " " + + "
" + + "
" + + "
" + + "
" + + " " + + "
" + + "
" + + " album image" + + "
" + + "
" + + "
    " + + "
  • " + + "

    Album Name:

    " + + " " + album.name + "" + + "
  • " + + "
  • " + + "

    Artist Name:

    " + + " " + album.artistName + "" + + "
  • " + + "
  • " + + "

    Released date:

    " + + " " + album.releaseDate + "" + + "
  • " + + "
  • " + + "

    Songs:

    " + + songs + + "
" + + "
" + + "
" + + " " + + + "
" + // end of panel-body + + " " + + + "
" + + "
" + + " "; // render to the page with jQuery + $('#albums').append(albumHtml); + } + +}); \ No newline at end of file diff --git a/seed.js b/seed.js index 1943f8f..ea4fae6 100644 --- a/seed.js +++ b/seed.js @@ -5,6 +5,30 @@ var db = require("./models"); var albumsList =[ // put data here! + { + artistName: 'Nine Inch Nails', + name: 'The Downward Spiral', + releaseDate: '1994, March 8', + genres: [ 'industrial', 'industrial metal' ] + }, + { + artistName: 'Metallica', + name: 'Metallica', + releaseDate: '1991, August 12', + genres: [ 'heavy metal' ] + }, + { + artistName: 'The Prodigy', + name: 'Music for the Jilted Generation', + releaseDate: '1994, July 4', + genres: [ 'electronica', 'breakbeat hardcore', 'rave', 'jungle' ] + }, + { + artistName: 'Johnny Cash', + name: 'Unchained', + releaseDate: '1996, November 5', + genres: [ 'country', 'rock' ] + } ]; db.Album.remove({}, function(err, albums){ @@ -17,3 +41,41 @@ db.Album.remove({}, function(err, albums){ }); }); + + /* Approximate schema for these seeds +var SongSchema = new Schema({ + name: String, + trackNumber: Number, +}); +*/ + + +var sampleSongs = []; + +sampleSongs.push({ name: 'Swamped', + trackNumber: 1 +}); +sampleSongs.push({ name: "Heaven's a Lie", + trackNumber: 2 +}); +sampleSongs.push({ name: 'Daylight Dancer', + trackNumber: 3 +}); +sampleSongs.push({ name: 'Humane', + trackNumber: 4 +}); +sampleSongs.push({ name: 'Self Deception', + trackNumber: 5 +}); +sampleSongs.push({ name: 'Aeon', + trackNumber: 6 +}); +sampleSongs.push({ name: 'Tight Rope', + trackNumber: 7 +}); + +albumsList.forEach( function ( element, index) { + element.songs = sampleSongs; +}); + +console.log(albumsList); \ No newline at end of file diff --git a/server.js b/server.js index 5da137b..6fb784d 100644 --- a/server.js +++ b/server.js @@ -1,63 +1,37 @@ // SERVER-SIDE JAVASCRIPT - +var mongoose = require('mongoose'); //require express in our app var express = require('express'); // generate a new express app and call it 'app' var app = express(); +// configure bodyParser (for receiving form data) +var bodyParser = require("body-parser"); +// parse POSTed data +app.use(bodyParser.urlencoded({extended: true})); + // serve static files from public folder app.use(express.static(__dirname + '/public')); +/* + * HTML Endpoints + */ +//for client req to server, res 'Hello World' +app.get('/', function (req, res) { + res.sendFile('views/index.html' , { root : __dirname}); +}); + + /************ * DATABASE * ************/ -/* hard-coded data */ -var albums = []; -albums.push({ - _id: 132, - artistName: 'Nine Inch Nails', - name: 'The Downward Spiral', - releaseDate: '1994, March 8', - genres: [ 'industrial', 'industrial metal' ] - }); -albums.push({ - _id: 133, - artistName: 'Metallica', - name: 'Metallica', - releaseDate: '1991, August 12', - genres: [ 'heavy metal' ] - }); -albums.push({ - _id: 134, - artistName: 'The Prodigy', - name: 'Music for the Jilted Generation', - releaseDate: '1994, July 4', - genres: [ 'electronica', 'breakbeat hardcore', 'rave', 'jungle' ] - }); -albums.push({ - _id: 135, - artistName: 'Johnny Cash', - name: 'Unchained', - releaseDate: '1996, November 5', - genres: [ 'country', 'rock' ] - }); - - +var db = require("./models/index.js"); /********** * ROUTES * **********/ -/* - * HTML Endpoints - */ - -app.get('/', function homepage (req, res) { - res.sendFile(__dirname + '/views/index.html'); -}); - - /* * JSON API Endpoints */ @@ -73,6 +47,64 @@ app.get('/api', function api_index (req, res){ }); }); +app.get('/api/albums', function (req, res) { + db.Album.find(function (err, Album) { + res.json(Album); + }); +}); + + +//https://github.com/sf-wdi-25/notes/tree/master/week-04-mongo-database/day-01-mongo/dusk-schemas_and_embedding +app.post('/api/albums', function create(req, res) { + // console.log(req.body); + + var genres = req.body.genres.split(',').map(function(item) { + return item.trim(); } ); + req.body.genres = genres; + + db.Album.create(req.body, function (err, newAlbum) { + if (err) { console.log('error', err); } + // console.log(newAlbum); + res.json(newAlbum); + }); + +}); + + +app.get('/api/albums/:id', function albumShow(req, res) { + console.log('requested album id=', req.params.id); + db.Album.findOne({_id: req.params.id}, function(err, album) { + res.json(album); + }); +}); + +app.post('/api/albums/:albumId/songs', function songsCreate(req, res) { + console.log('body', req.body); + + db.Album.findOne({_id: req.params.albumId}, function(err, album) { + if (err) { console.log('error', err); } + + var song = new db.Song(req.body); + album.songs.push(song); + album.save(function(err, savedAlbum) { + if (err) { console.log('error', err); } + console.log('album with new song saved:', savedAlbum); + res.json(song); + }); + }); + +}); + +app.delete('/api/albums/:id', function deleteAlbum(req, res) { + console.log('deleting id: ', req.params.id); + db.Album.remove({_id: req.params.id}, function(err) { + if (err) { return console.log(err); } + console.log("removal of id=" + req.params.id + " successful."); + res.status(200).send(); // everything is a-OK + }); +}); + + /********** * SERVER * **********/ @@ -80,4 +112,4 @@ app.get('/api', function api_index (req, res){ // listen on port 3000 app.listen(process.env.PORT || 3000, function () { console.log('Express server is running on http://localhost:3000/'); -}); +}); \ No newline at end of file diff --git a/views/index.html b/views/index.html index 5cb6501..18d995a 100644 --- a/views/index.html +++ b/views/index.html @@ -15,7 +15,8 @@ - + +
@@ -25,66 +26,77 @@

Welcome to tunely

-
-
-
-

Albums

-
-
- -
- + +
+
+
+
+
- -
- -
-
-
- + + Add New Album - -
-
- album image -
+ +
+ +
+ -
-
    -
  • -

    Album Name:

    - Ladyhawke -
  • +
+
-
  • -

    Artist Name:

    - Ladyhawke -
  • + +
    + +
    + -
  • -

    Released date:

    - 2008, November 18 -
  • - -
    +
    +
    -
    - + +
    + +
    + - +
    +
    -
    + +
    + +
    +
    -
    - + +
    + +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Albums

    +
    +
    + +