Commit b1b2f81a

mo khan <mo@mokhan.ca>
2014-10-04 03:19:46
render profiles page in backbone.
1 parent 9afe0ef
app/assets/javascripts/backbone/controllers/profile_controller.js.coffee
@@ -0,0 +1,16 @@
+class CakeSide.Controllers.ProfileController extends Marionette.Controller
+  views: CakeSide.Views.Profiles
+  initialize: (options) ->
+    @content_region = CakeSide.Application.content_region
+
+  show: ->
+    @selectTab()
+    profile = new CakeSide.Models.Profile
+      id: 'me'
+    profile.fetch
+      success: =>
+        @content_region.show(new @views.ShowView(model: profile))
+
+  selectTab: ->
+    $('.nav-list').children().removeClass('active')
+    $('#settings-tab').addClass('active')
app/assets/javascripts/backbone/models/profile.js.coffee
@@ -0,0 +1,18 @@
+class CakeSide.Models.Profile extends Backbone.Model
+  paramRoot: 'profile'
+  urlRoot: '/api/v1/profiles'
+  modelEvents:
+    "change": "render"
+
+  defaults:
+    id: null
+    name: null
+    email: null
+    city: null
+    website: null
+    facebook: null
+    twitter: null
+
+class CakeSide.Collections.ProfilesCollection extends Backbone.Collection
+  model: CakeSide.Models.Profile
+  url: '/api/v1/profiles'
app/assets/javascripts/backbone/routers/profile_router.js.coffee
@@ -0,0 +1,3 @@
+class CakeSide.Routers.ProfileRouter extends Marionette.AppRouter
+  appRoutes:
+    "profile": "show"
app/assets/javascripts/backbone/templates/cakes/new.jst.ejs
@@ -1,30 +1,26 @@
-<div class="row-fluid">
-  <div class="span12">
-    <h1>Share cake</h1>
-    <hr />
-    <form id="new-cake" name="cake" class="form-horizontal">
-      <fieldset>
-        <div class="control-group">
-          <label class="control-label" for="cake_name">Name*</label>
-          <div class="controls">
-            <input class="input-xxlarge" id="cake_name" name="name" type="text">
-          </div>
-        </div>
-        <div class="control-group">
-          <label class="control-label">Category</label>
-          <div class="controls">
-            <select id="cake_category_id" name="category_id">
-              <% _.each(categories, function(category) { %>
-              <option value="<%= category.id %>"><%= category.name %></option>
-              <% }); %>
-            </select>
-          </div>
-        </div>
-        <div class="form-actions">
-          <button id='save-button' type="submit" class="btn btn-primary">Create</button>
-          <a href="#cakes" class="btn">Cancel</a>
-        </div>
-      </fieldset>
-    </form>
-  </div>
-</div>
+<h1>Share cake</h1>
+<hr />
+<form id="new-cake" name="cake" class="form-horizontal">
+  <fieldset>
+    <div class="control-group">
+      <label class="control-label" for="cake_name">Name*</label>
+      <div class="controls">
+        <input class="input-xxlarge" id="cake_name" name="name" type="text">
+      </div>
+    </div>
+    <div class="control-group">
+      <label class="control-label">Category</label>
+      <div class="controls">
+        <select id="cake_category_id" name="category_id">
+          <% _.each(categories, function(category) { %>
+          <option value="<%= category.id %>"><%= category.name %></option>
+          <% }); %>
+        </select>
+      </div>
+    </div>
+    <div class="form-actions">
+      <button id='save-button' type="submit" class="btn btn-primary">Create</button>
+      <a href="#cakes" class="btn">Cancel</a>
+    </div>
+  </fieldset>
+</form>
app/assets/javascripts/backbone/templates/profiles/show.jst.ejs
@@ -0,0 +1,35 @@
+<h1>Public Profile</h1>
+<hr />
+<form id="profile-form" class="form-horizontal">
+  <fieldset>
+    <div class="control-group">
+      <label class="control-label" for="user_name">Name</label>
+      <div class="controls"> <input class="input-xlarge" id="user_name" name="user[name]" type="text" value="<%= name %>"> </div>
+    </div>
+    <div class="control-group">
+      <label class="control-label" for="user_email">Email</label>
+      <div class="controls"> <input class="input-xlarge" id="user_email" name="user[email]" type="email" value="<%= email %>"> </div>
+    </div>
+    <div class="control-group">
+      <label class="control-label" for="user_city">City</label>
+      <div class="controls"> <input class="input-xlarge" id="user_city" name="user[city]" type="text" value="<%= city %>"> </div>
+    </div>
+    <div class="control-group">
+      <label class="control-label" for="user_website">Website</label> 
+      <div class="controls"> <input class="input-xlarge url" id="user_website" name="user[website]" placeholder="https://www.cakeside.com" type="url" value="<%= website %>"> </div>
+    </div>
+    <div class="control-group">
+      <label class="control-label" for="user_twitter">Twitter username @</label> 
+      <div class="controls"> <input class="input-xlarge" id="user_twitter" maxlength="255" name="user[twitter]" placeholder="without the @ sign" size="255" type="text" value="<%= twitter %>"> </div>
+    </div>
+    <div class="control-group">
+      <label class="control-label" for="user_facebook">Facebook</label> 
+      <div class="controls"> <input class="input-xlarge" id="user_facebook" maxlength="255" name="user[facebook]" placeholder="http://www.facebook.com/your_profile" size="255" type="text" value="<%= facebook %>"> </div>
+    </div>
+    <div class="form-actions">
+      <input id="save-button" type="submit" class="btn btn-primary" value="Save changes">
+      <button type="reset" class="btn">Cancel</button>
+    </div>
+  </fieldset>
+</form>
+
app/assets/javascripts/backbone/templates/tutorials/new.jst.ejs
@@ -1,39 +1,33 @@
-<div class="row">
-  <div class="span9">
-    <h1>Share a tutorial link</h1>
-    <hr />
-    <form id="new-tutorial" name='tutorial' class='form-horizontal'>
-      <fieldset>
-        <div id="url-group" class="control-group">
-          <label class="control-label" for="tutorial_url">Tutorial URL</label>
-          <div class="controls">
-            <input class="input-xxlarge" id="tutorial_url" name="url" type="text" value="<%= url %>" placeholder="http://www.cakeside.com/" autofocus>
-          </div>
-        </div>
-        <div class="control-group">
-          <label for="tags" class="control-label">Tags</label>
-            <div class="controls">
-              <input type="text" id="tutorial_tags" name="tags" value="" class="input-xxlarge" autocomplete="off" />
-              <p class="help-block">
-                Note: help people find this tutorial by adding some keyword tags
-              </p>
-            </div>
-        </div>
-        <div class="form-actions">
-          <button id='save-button' type="submit" class="btn btn-primary">Save</button>
-          <a href="#tutorials" class="btn">Cancel</a>
-        </div>
-      </fieldset>
-    </form>
-  </div>
-  <div class="span3">
-    <div id="preview-panel" class="thumbnail">
-      <img class="embed-thumb" src="<%= image_url %>" />
-      <div class="caption">
-        <h3 class="tutorial-heading"><%= heading %></h3>
-        <p id="tag-list"></p>
-        <p class="tutorial-description"><%= description %></p>
+<h1>Share a tutorial link</h1>
+<hr />
+<form id="new-tutorial" name='tutorial' class='form-horizontal'>
+  <fieldset>
+    <div id="url-group" class="control-group">
+      <label class="control-label" for="tutorial_url">Tutorial URL</label>
+      <div class="controls">
+        <input class="input-xxlarge" id="tutorial_url" name="url" type="text" value="<%= url %>" placeholder="http://www.cakeside.com/" autofocus>
+      </div>
+    </div>
+    <div class="control-group">
+      <label for="tags" class="control-label">Tags</label>
+      <div class="controls">
+        <input type="text" id="tutorial_tags" name="tags" value="" class="input-xxlarge" autocomplete="off" />
+        <p class="help-block">
+        Note: help people find this tutorial by adding some keyword tags
+        </p>
       </div>
     </div>
+    <div class="form-actions">
+      <button id='save-button' type="submit" class="btn btn-primary">Save</button>
+      <a href="#tutorials" class="btn">Cancel</a>
+    </div>
+  </fieldset>
+</form>
+<div id="preview-panel" class="thumbnail">
+  <img class="embed-thumb" src="<%= image_url %>" />
+  <div class="caption">
+    <h3 class="tutorial-heading"><%= heading %></h3>
+    <p id="tag-list"></p>
+    <p class="tutorial-description"><%= description %></p>
   </div>
 </div>
app/assets/javascripts/backbone/views/profiles/show_view.js.coffee
@@ -0,0 +1,46 @@
+CakeSide.Views.Profiles ||= {}
+
+class CakeSide.Views.Profiles.ShowView extends Marionette.ItemView
+  template: JST["backbone/templates/profiles/show"]
+  ui:
+    name: '#user_name'
+    email: '#user_email'
+    city: '#user_city'
+    website: '#user_website'
+    facebook: '#user_facebook'
+    twitter: '#user_twitter'
+    save_button: '#save-button'
+
+  modelEvents:
+    'invalid': 'displayError'
+
+  events:
+    "submit #profile-form": "save"
+    "keyup input": "refreshStatus"
+    "change select": "refreshStatus"
+
+  save: (event) ->
+    event.preventDefault()
+    event.stopPropagation()
+    @disableSaveButton()
+    @model.save()
+
+  enableSaveButton: ->
+    @ui.save_button.removeAttr('disabled')
+
+  disableSaveButton: ->
+    @ui.save_button.attr('disabled', 'disabled')
+
+  displayError: ->
+    @disableSaveButton()
+
+  refreshStatus: ->
+    @enableSaveButton()
+    @model.set('name', @ui.name.val())
+    @model.set('email', @ui.email.val())
+    @model.set('city', @ui.city.val())
+    @model.set('website', @ui.website.val())
+    @model.set('facebook', @ui.facebook.val())
+    @model.set('twitter', @ui.twitter.val())
+    @model.isValid()
+
app/assets/javascripts/backbone/cakeside.js.coffee
@@ -28,6 +28,8 @@ window.CakeSide =
         controller: new CakeSide.Controllers.TutorialsController()
       new CakeSide.Routers.DashboardRouter
         controller: new CakeSide.Controllers.DashboardController()
+      new CakeSide.Routers.ProfileRouter
+        controller: new CakeSide.Controllers.ProfileController()
 
     CakeSide.Application.on 'start', ->
       if Backbone.history
@@ -58,6 +60,8 @@ window.CakeSide =
         photos
     CakeSide.Application.reqres.setHandler 'TutorialsRepository', =>
       @tutorials
+    CakeSide.Application.reqres.setHandler 'ProfilesRepository', =>
+      @profiles ||= new CakeSide.Collections.ProfilesCollection()
 
     @cakes.fetch(reset: true).done ->
       CakeSide.Application.start()
app/controllers/api/v1/profiles_controller.rb
@@ -0,0 +1,20 @@
+module Api
+  module V1
+    class ProfilesController < ApiController
+      def show
+        @profile = current_user
+      end
+
+      def update
+        @profile = current_user
+        @profile.update(secure_params)
+      end
+
+      private
+
+      def secure_params
+        params.require(:profile).permit(:name, :email, :city, :website, :twitter, :facebook)
+      end
+    end
+  end
+end
app/models/user_session.rb
@@ -3,7 +3,7 @@ class UserSession < ActiveRecord::Base
   has_one :location, as: :locatable
   before_create :set_unique_key
   attr_readonly :key
-  scope :active, -> { where("accessed_at >= ?", 2.weeks.ago).where(revoked_at: nil).includes(:user, :location) }
+  scope :active, -> { where("accessed_at >= ?", 2.weeks.ago).where(revoked_at: nil).includes(:user) }
 
   def revoke!
     self.revoked_at = Time.now
app/views/api/v1/cakes/update.json.jbuilder
@@ -0,0 +1,1 @@
+json.partial! 'cake', cake: @cake
app/views/api/v1/profiles/_profile.json.jbuilder
@@ -0,0 +1,8 @@
+json.id profile.id
+json.email profile.email
+json.name profile.name
+json.website profile.website
+json.twitter profile.twitter
+json.facebook profile.facebook
+json.city profile.city
+json.errors profile.errors
app/views/api/v1/profiles/show.json.jbuilder
@@ -0,0 +1,1 @@
+json.partial! 'profile', profile: @profile
app/views/api/v1/profiles/update.json.jbuilder
@@ -0,0 +1,1 @@
+json.partial! 'profile', profile: @profile
config/routes.rb
@@ -58,14 +58,15 @@ Cake::Application.routes.draw do
 
   root to: "creations#index"
 
-  namespace :api, :defaults => { :format => 'json' }  do
+  namespace :api, defaults: { :format => 'json' }  do
     namespace :v1 do
       resources :cakes, only: [:index, :show, :create, :update, :destroy] do
         resources :photos, only: [:index, :show, :create]
       end
       resources :categories, only: [:index]
       resources :tutorials, only: [:index, :create]
-      resources :logins, :only => [:create]
+      resources :profiles, only: [:show, :update]
+      resources :logins, only: [:create]
     end
   end