Commit b1b2f81a
Changed files (15)
app
assets
javascripts
backbone
controllers
models
routers
templates
views
profiles
controllers
api
models
views
api
v1
config
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