diff --git a/dist/index.html b/dist/index.html index 559b18ecd..f0a610968 100644 --- a/dist/index.html +++ b/dist/index.html @@ -2,14 +2,87 @@ + Backbone Baseline + -
- -
+
+
+

IK Movies

+

Made with Backbone blood, API sweat, and Ruby on Rails tears ( Iuliia & Kee )

+
+ + + +
+
+
    +
    + +
    +
    +
    +
    +
    + + + + + + diff --git a/src/app.js b/src/app.js index 30c00d594..9d360646a 100644 --- a/src/app.js +++ b/src/app.js @@ -1,14 +1,75 @@ -import 'css/_settings.css'; -import 'foundation-sites/dist/css/foundation.css'; -import './css/styles.css'; - // Import jQuery & Underscore import $ from 'jquery'; import _ from 'underscore'; +import 'foundation-sites'; + +// CSS +import styles from './css/styles.css'; + +// Models and views +import Movie from './models/movie'; +import MovieList from './collections/movie_list'; +import MovieView from './views/movie_view'; +import MovieListView from './views/movie_list_view'; +import ShowView from './views/show_view'; -// ready to go +// Define Variables +let movieTemplate; +let showTemplate; + +// Ready to go $(document).ready(function() { + // Event Bus + let bus = {}; + bus = _.extend(bus, Backbone.Events); + + // Templates + movieTemplate = _.template($('#movie-template').html()); + showTemplate = _.template($('#show-template').html()); + + const movieList = new MovieList(); + const searchList = new MovieList(); + + const movieListView = new MovieListView({ + el: $('.movies'), + model: movieList, + collection: searchList, + template: movieTemplate, + bus: bus, + }); + + const showView = new ShowView({ + el: $('section.movie div.details-wrapper'), + template: showTemplate, + bus: bus, + collection: movieList + }) + + movieList.fetch(); + + // Search event + $('#search-form').on('submit', function(e){ + e.preventDefault(); + let queryText = $('#search-form input').val(); + + if (queryText.length > 0 ) { + movieListView.searchMode(); + searchList.fetch({ + data: {query: queryText}, + }); + } + $('#search-form input').val(''); + }); - $('#main-content').append('

    Hello World!

    '); + // Rental Library + $('#movies').on('click', function(){ + movieListView.inventoryMode(); + movieList.fetch(); + }); + // Styling + $('li.movie').on('click', function() { + $('li.movie').removeClass('highlighted'); + $(this).addClass('highlighted'); + }) }); diff --git a/src/collections/movie_list.js b/src/collections/movie_list.js new file mode 100644 index 000000000..bba95a229 --- /dev/null +++ b/src/collections/movie_list.js @@ -0,0 +1,12 @@ +import Backbone from 'backbone'; +import Movie from '../models/movie'; + +const MovieList = Backbone.Collection.extend({ + model: Movie, + url: `http://localhost:3000/movies`, + parse: function(response) { + return response; + }, +}); + +export default MovieList; diff --git a/src/css/styles.css b/src/css/styles.css index 68a79a569..9207866f9 100644 --- a/src/css/styles.css +++ b/src/css/styles.css @@ -1,44 +1,153 @@ -@include foundation-everything; +/*----------------- imports -----------------*/ +/* fontawesome, foundation, google fonts */ +@import url("https://use.fontawesome.com/releases/v5.0.2/css/all.css"); +@import url("https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.min.css"); +@import url('https://fonts.googleapis.com/css?family=Cabin|PT+Sans:400,700'); -main { - background: lightblue; -} +/*----------------- big parts-----------------*/ +/* test */ +/** { border: 1px solid red !important; }*/ -header { - background-color: lightgreen; - padding: 0.5rem; +html { box-sizing: border-box; } +*, *:before, *:after { box-sizing: inherit; } +html, body { + width: 100%; + height: 100%; } +body { + display: flex; + flex-direction: column; -#completed-checkbox { - display: inline; + padding: 0; + font-size: 16px; + font-family: 'Cabin', sans-serif; + color: #333; + overflow-x: hidden; } - -label { - display: inline; +h1, h2, h3, h4, h5, h6, button { + font-family: 'PT Sans', sans-serif; +} +.fas { margin-right: 0.4rem; } +.fa-camera, .fa-heart {margin-right: 0;} +.highlighted { border: 5px solid #f9dc48; } +button.button { + background: #f9dc48; + color: #333; + border-radius: 2px; +} +button.button:hover, +button.button:active, +button.button:focus { + background: #f7bc3d; + color: #333; +} +.content-wrapper { + flex: 1 0 auto; + background: #c8c5cc; +} +footer { + padding-top: 1rem; + text-align: center; + background: #555; + color: #fcfcfc; + height: 70px; } -button.success { - margin-right: 1.2rem; - display: inline; +/*----------------- header -----------------*/ +header { + background-color: #857c8e; + padding: 0.6rem; +} +h1.main-title { + font-weight: 700; + color: #fefefe; + text-align: center; +} +p.sub-head { + color: #ddd; + text-align: center; } -aside.create-tasklist { - background-color: navy; - color: #FFFFFF; +/*----------------- nav -----------------*/ +nav.main-nav { + padding: 0.5rem 0; + width: 100%; + background-color: #ada6b5; + text-align: center; } -aside label { - color: #FFFFFF; +form#search-form { + display: inline-block; + width: 60%; +} +form#search-form input[name="search"], +button#search, +button#movies { + height: 3rem; + display: inline-block; +} +form#search-form input[name="search"] { + width: 50%; + margin-right: 5%; + padding-left: 2%; + border-radius: 2px; +} +button#search, +button#movies { + margin-top: .7rem; + width: 20%; } -.completed { - text-decoration: line-through; +/*----------------- list -----------------*/ +section.movies { + padding-top: 1rem; + overflow: auto; +} +ul.movies-list li.movie { + list-style-type: none; + margin: 1rem; + width: 26%; +} +div.card { + margin-bottom: 0; + border: none; + background: #f0f0f0; +} +div.card img { + height: 11rem; + display: inline-block; + filter: grayscale(100%); +} +div.card-section { padding: 0.5em; } +div.card-section h6, +div.card-section p { + text-align: center; +} +div.card-section h6 { margin-bottom: 0; } +div.card-section p { + color: #888; + font-size: 0.7em; } -div { - display: inline; +/*----------------- details -----------------*/ +section.movie { padding: 2rem; } +div.details-wrapper { + background: #f0f0f0; + height: auto; + border-radius: 2px; +} +div.img-detail { text-align: center; } +div.img-detail img { + max-width: 210px; + padding: 1em 0 1.5em; +} +p.movie-summary { color: #555; font-size: 0.9rem; } +div.text-detail { padding: 1em 0 2em; } +div.large-7 button.add-collection { + display: block; + margin: 2em auto 0; + text-align: center; } -/* -* { - border-style: solid; +div.callout { + margin-top: 2em; + text-align: center; } -*/ diff --git a/src/models/movie.js b/src/models/movie.js new file mode 100644 index 000000000..4e2911dc7 --- /dev/null +++ b/src/models/movie.js @@ -0,0 +1,15 @@ +import Backbone from 'backbone'; + +const Movie = Backbone.Model.extend({ + defaults: { + inInventory: true, + image_url: '' + }, + url: `http://localhost:3000/movies/`, + parse: function(response) { + return response; + }, + comparator: 'title', +}); + +export default Movie; diff --git a/src/views/movie_list_view.js b/src/views/movie_list_view.js new file mode 100644 index 000000000..2a388ea16 --- /dev/null +++ b/src/views/movie_list_view.js @@ -0,0 +1,69 @@ +import Backbone from 'backbone'; +import MovieView from './movie_view'; +import Movie from '../models/movie'; + +const MovieListView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.bus = params.bus; + this.collection = params.collection; + + this.listenTo(this.model, 'update', this.render); + this.listenTo(this.collection, 'update', this.render); + + this.mode = "inventory"; + }, + + inventoryMode() { + this.mode = "inventory"; + }, + + searchMode() { + this.mode = "search"; + }, + + events: { + "click li.movie" : "toggleHighlight" + }, + + toggleHighlight(event) { + let active = event.currentTarget; + this.$el.find('li.movie').attr('class', 'movie highlighted'); + this.$el.find('li.movie').not(active).attr('class', 'movie'); + }, + + render() { + this.$('ul').empty(); + + if (this.mode == "search") { + this.collection.forEach((movie) => { + const movieView = new MovieView({ + bus: this.bus, + model: movie, + template: this.template, + tagName: 'li', + className: 'movie', + collection: this.model, + }); + this.$('ul').append(movieView.render().$el); + }); + } else if (this.mode == "inventory"){ + this.model.forEach((movie) => { + const movieView = new MovieView({ + bus: this.bus, + model: movie, + template: this.template, + tagName: 'li', + className: 'movie', + collection: this.model, + }); + this.$('ul').append(movieView.render().$el); + }); + } else { + console.error(`Invalid movie list mode ${this.mode}`); + } + return this; + }, +}); + +export default MovieListView; diff --git a/src/views/movie_view.js b/src/views/movie_view.js new file mode 100644 index 000000000..8110d6bc4 --- /dev/null +++ b/src/views/movie_view.js @@ -0,0 +1,30 @@ +import Backbone from 'backbone'; +import Movie from '../models/movie'; +import MovieList from '../collections/movie_list'; + +const MovieView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.bus = params.bus; + this.collection = params.collection; + }, + + render() { + const compiledTemplate = this.template(this.model.toJSON()); + this.$el.html(compiledTemplate); + return this; + }, + + events: { + 'click': 'showMovie', + }, + + showMovie(event){ + let found = this.collection.where({overview: this.model.get('overview')}).length > 0; + this.model.set('inInventory', found); + + this.bus.trigger('addToCollection', this.model); + }, +}); + +export default MovieView; diff --git a/src/views/show_view.js b/src/views/show_view.js new file mode 100644 index 000000000..d4690cc70 --- /dev/null +++ b/src/views/show_view.js @@ -0,0 +1,37 @@ +import Backbone from 'backbone'; +import Movie from '../models/movie'; + +const ShowView = Backbone.View.extend({ + initialize(params) { + this.collection = params.collection; + this.bus = params.bus; + this.template = params.template; + this.model; + + this.listenTo(this.bus, 'addToCollection', this.render); + this.listenTo(this.collection, 'update', this.render); + }, + + render(movieData) { + this.$el.html(''); + const compiledTemplate = this.template(movieData.attributes); + this.$el.html(compiledTemplate); + + this.model = movieData; + }, + + events: { + 'click button.add-collection': 'addtoLibrary' + }, + + addtoLibrary() { + let saved = this.model.save(); + if (saved) { + this.collection.add(this.model); + let theButton = this.$('button.add-collection'); + this.model.set('inInventory', true); + } + } +}); + +export default ShowView;