mirror of
				https://github.com/fspc/BikeShed-1.git
				synced 2025-10-31 08:55:36 -04:00 
			
		
		
		
	Merge pull request #118 from ilya-konanykhin/issue-105-106
Issue #105, #106: photo upload for User & Bike
This commit is contained in:
		
						commit
						b8ba64ab93
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -7,5 +7,6 @@ tmp/ | ||||
| .rbenv-version | ||||
| .DS_Store | ||||
| public/assets | ||||
| public/system | ||||
| config/database.yml | ||||
| .idea/ | ||||
							
								
								
									
										1
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Gemfile
									
									
									
									
									
								
							| @ -18,6 +18,7 @@ gem 'jquery-rails', '~> 2.0' | ||||
| gem 'pg', '~> 0.17.1' | ||||
| gem 'will_paginate', '~> 3.0.3' | ||||
| gem 'jbuilder', '~> 2.0.3' | ||||
| gem 'paperclip', '~> 4.3' | ||||
| 
 | ||||
| # Assets | ||||
| gem 'sass-rails', '~> 3.0' | ||||
|  | ||||
							
								
								
									
										11
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Gemfile.lock
									
									
									
									
									
								
							| @ -57,7 +57,10 @@ GEM | ||||
|       xpath (~> 2.0) | ||||
|     childprocess (0.5.9) | ||||
|       ffi (~> 1.0, >= 1.0.11) | ||||
|     climate_control (0.1.0) | ||||
|     cliver (0.3.2) | ||||
|     cocaine (0.5.8) | ||||
|       climate_control (>= 0.0.3, < 1.0) | ||||
|     coderay (1.1.1) | ||||
|     coffee-rails (3.2.2) | ||||
|       coffee-script (>= 2.2.0) | ||||
| @ -129,6 +132,7 @@ GEM | ||||
|       treetop (~> 1.4.8) | ||||
|     method_source (0.8.2) | ||||
|     mime-types (1.25.1) | ||||
|     mimemagic (0.3.0) | ||||
|     mini_portile2 (2.0.0) | ||||
|     momentjs-rails (2.15.1) | ||||
|       railties (>= 3.1) | ||||
| @ -148,6 +152,12 @@ GEM | ||||
|       nenv (~> 0.1) | ||||
|       shellany (~> 0.0) | ||||
|     orm_adapter (0.0.7) | ||||
|     paperclip (4.3.7) | ||||
|       activemodel (>= 3.2.0) | ||||
|       activesupport (>= 3.2.0) | ||||
|       cocaine (~> 0.5.5) | ||||
|       mime-types | ||||
|       mimemagic (= 0.3.0) | ||||
|     pg (0.17.1) | ||||
|     poltergeist (1.5.1) | ||||
|       capybara (~> 2.1) | ||||
| @ -261,6 +271,7 @@ DEPENDENCIES | ||||
|   netzke-basepack (~> 0.8.0) | ||||
|   netzke-cancan | ||||
|   netzke-core (~> 0.8.0) | ||||
|   paperclip (~> 4.3) | ||||
|   pg (~> 0.17.1) | ||||
|   poltergeist (~> 1.5.0) | ||||
|   pry (~> 0.9.8) | ||||
|  | ||||
| @ -16,4 +16,5 @@ | ||||
| //= require utils
 | ||||
| //= require moment
 | ||||
| //= require bootstrap-datetimepicker
 | ||||
| //= require jquery.form
 | ||||
| 
 | ||||
|  | ||||
| @ -1,31 +1,11 @@ | ||||
| $('.btn').button(); | ||||
| 
 | ||||
| $("#add_bike_submit").click(function(){ | ||||
| 
 | ||||
|   json_data = { bikes: [{ | ||||
|       serial_number:      $("#serial_number").val(), | ||||
|       bike_brand_id:      parseInt($("#bike_brand_id").val()), | ||||
|       shop_id:            parseInt($("#shop_id").val()), | ||||
|       model:              $("#model").val(), | ||||
|       bike_style_id:      parseInt($('input[name=bike_style]:checked').val()), | ||||
|       seat_tube_height:   parseFloat($("#seat_tube_height").val()), | ||||
|       bike_condition_id:  parseInt($('input[name=bike_condition]:checked').val()), | ||||
|       bike_purpose_id:    1, | ||||
|       bike_wheel_size_id: parseInt($("#bike_wheel_size_id").val()), | ||||
|     }]}; | ||||
| 
 | ||||
|   $.ajax({ | ||||
|     url: $("#add_bike_submit").data("url"), | ||||
|     type: "POST", | ||||
|     data: JSON.stringify(json_data), | ||||
|     contentType: 'application/json', | ||||
| $("#add_bike_form").ajaxForm({ | ||||
|     dataType: "json", | ||||
|     success: function(data, status, xhr){ | ||||
|     success: function(data){ | ||||
|       window.location = data.bikes[0].id + "?add_bike=1"; | ||||
|     }, | ||||
|     error: function(data, status ){ | ||||
|     error: function(data){ | ||||
|       displayFormErrors(data.responseJSON); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
| }); | ||||
| }) | ||||
| @ -2,50 +2,79 @@ $(document).ready(function(){ | ||||
|   var MIN_LEN = 3; | ||||
|   var MAX_SUBMITS = 3; | ||||
|   var submit_count = 0; | ||||
|   $("input[name=commit]").click( function(e){ | ||||
|     console.log("clicked"); | ||||
|     submit_count += 1; | ||||
|     //IDs of contact info
 | ||||
|     var contact_info_ids = [ | ||||
|       "user_email", | ||||
|       "user_user_profiles_attributes_0_addrStreet1", | ||||
|       "user_user_profiles_attributes_0_addrCity", | ||||
|       "user_user_profiles_attributes_0_addrState", | ||||
|       "user_user_profiles_attributes_0_addrZip", | ||||
|       "user_user_profiles_attributes_0_phone" | ||||
|     ]; | ||||
|     var contact_vals = ""; | ||||
|     var index = 0; | ||||
|     //see if any contact info exists
 | ||||
|     for( var index in contact_info_ids){ | ||||
|       contact_vals += $("#"+contact_info_ids[index]).val(); | ||||
|     } | ||||
|     if( contact_vals.length >= MIN_LEN || submit_count > MAX_SUBMITS){ | ||||
| 
 | ||||
|       if( submit_count > MAX_SUBMITS ){ | ||||
|         alert("Fine."); | ||||
|   var checkContacts = function() { | ||||
|       submit_count += 1; | ||||
|       //IDs of contact info
 | ||||
|       var contact_info_ids = [ | ||||
|           "user_email", | ||||
|           "user_user_profiles_attributes_0_addrStreet1", | ||||
|           "user_user_profiles_attributes_0_addrCity", | ||||
|           "user_user_profiles_attributes_0_addrState", | ||||
|           "user_user_profiles_attributes_0_addrZip", | ||||
|           "user_user_profiles_attributes_0_phone" | ||||
|       ]; | ||||
| 
 | ||||
|       var contact_vals = ""; | ||||
|       //see if any contact info exists
 | ||||
|       for( var index in contact_info_ids){ | ||||
|           contact_vals += $("#"+contact_info_ids[index]).val(); | ||||
|       } | ||||
|       return true; | ||||
|       if( contact_vals.length >= MIN_LEN || submit_count > MAX_SUBMITS){ | ||||
| 
 | ||||
|     }else{ | ||||
|           if( submit_count == MAX_SUBMITS + 1 ){ | ||||
|               alert("Fine."); | ||||
|           } | ||||
|           return true; | ||||
| 
 | ||||
|       switch(submit_count){ | ||||
|         case 1: | ||||
|           alert("It appears you have not entered any contact information.  " + | ||||
|             "Please do."); | ||||
|           break; | ||||
|         case 2: | ||||
|           alert("It is highly recommended that you enter at least one form of" + | ||||
|             " contact information.  It is in your best interest."); | ||||
|           break; | ||||
|         case 3: | ||||
|           alert("If something happens to your bicycle, we will not be able to" + | ||||
|             " notify you.  Please enter at least one form of contact."); | ||||
|           break; | ||||
|         default: | ||||
|           alert("Please enter at least one form of contact."); | ||||
|       }else{ | ||||
| 
 | ||||
|           switch(submit_count){ | ||||
|               case 1: | ||||
|                   alert("It appears you have not entered any contact information.  " + | ||||
|                       "Please do."); | ||||
|                   break; | ||||
|               case 2: | ||||
|                   alert("It is highly recommended that you enter at least one form of" + | ||||
|                       " contact information.  It is in your best interest."); | ||||
|                   break; | ||||
|               case 3: | ||||
|                   alert("If something happens to your bicycle, we will not be able to" + | ||||
|                       " notify you.  Please enter at least one form of contact."); | ||||
|                   break; | ||||
|               default: | ||||
|                   alert("Please enter at least one form of contact."); | ||||
|           } | ||||
|           return false; | ||||
|       } | ||||
|       return false; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   var checkValid = function() { | ||||
|       var errors = {}; | ||||
|       var hasErrors = false; | ||||
|       ["username", "first_name", "last_name"].forEach(function(requiredField) { | ||||
|           if(!$("#user_" + requiredField).val().trim()) { | ||||
|               errors["user_" + requiredField] = ["can't be blank"]; | ||||
|               hasErrors = true; | ||||
|           } | ||||
|       }); | ||||
| 
 | ||||
|       if($("#user_password").val().length < 6) { | ||||
|           errors["user_password"] = ["is too short (minimum is 6 characters)"]; | ||||
|           hasErrors = true; | ||||
|       } | ||||
| 
 | ||||
|       if($("#user_password").val() != $("#user_password_confirmation").val()) { | ||||
|           errors["user_password_confirmation"] = ["confirmation doesn't match password"]; | ||||
|           hasErrors = true; | ||||
|       } | ||||
| 
 | ||||
|       displayFormErrors({errors: errors}, "#new_user"); | ||||
| 
 | ||||
|       return !hasErrors; | ||||
|   }; | ||||
| 
 | ||||
|   $("input[name=commit]").click(function(e){ | ||||
|       return checkContacts() && checkValid(); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| @ -1,8 +1,10 @@ | ||||
| function displayFormErrors(data){ | ||||
| function displayFormErrors(data, form){ | ||||
|   if(form){ | ||||
|     $(form).find(".form-group.has-error").removeClass("has-error").find(".help-block").html(""); | ||||
|   } | ||||
|   if(data.errors != undefined ){ | ||||
|     $.each(data.errors, function(field, errorMsg) { | ||||
|       $("#"+field).closest(".form-group").addClass("has-error"); | ||||
|       $("#"+field).siblings(".help-block").html(errorMsg); | ||||
|       $("#"+field).closest(".form-group").addClass("has-error").find(".help-block").html(errorMsg.join(", ")); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| class BikesController < AuthenticatedController | ||||
| 
 | ||||
|   def new | ||||
|     @bike = Bike.new bike_purpose_id: 1 | ||||
|     @brands = BikeBrand.all.map{ |b| [b.brand, b.id] } | ||||
|     @brands.unshift( ["Select a brand", -1] ) | ||||
|     @wheel_sizes = BikeWheelSize.all.map{ |w| [w.display_string, w.id] } | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| class Bike < ActiveRecord::Base | ||||
|   acts_as_loggable | ||||
|   attr_accessible :shop_id, :serial_number, :bike_brand_id, :model, :color, :bike_style_id, :seat_tube_height, | ||||
|     :top_tube_length, :bike_wheel_size_id, :value, :bike_condition_id, :bike_purpose_id | ||||
|     :top_tube_length, :bike_wheel_size_id, :value, :bike_condition_id, :bike_purpose_id, :photo | ||||
| 
 | ||||
|   has_many :transactions | ||||
| 
 | ||||
| @ -13,6 +13,8 @@ class Bike < ActiveRecord::Base | ||||
|   belongs_to :bike_purpose | ||||
|   belongs_to :bike_wheel_size | ||||
| 
 | ||||
|   has_attached_file :photo, :styles => {:thumb => '100x100>'} | ||||
| 
 | ||||
|   validates :shop_id, :presence => true, :uniqueness => true, :numericality => { :only_integer => true } | ||||
|   validates :serial_number, :length => { :minimum => 3 } | ||||
|   validates :model, :length => { :maximum => 50 } | ||||
| @ -24,6 +26,9 @@ class Bike < ActiveRecord::Base | ||||
|   validates :bike_condition_id, :presence => true, :numericality => { greater_than: 0, message: "is not a valid condition" } | ||||
|   validates :bike_purpose_id, :presence => true, :numericality => { greater_than: 0, message: "is not a valid purpose" } | ||||
| 
 | ||||
|   validates_attachment :photo,  :content_type => {:content_type => %w{ image/jpeg image/gif image/png }}, | ||||
|                                 :file_name => {:matches => [/png\Z/, /jpe?g\Z/, /gif\Z/]} | ||||
| 
 | ||||
|   self.per_page = 15 | ||||
| 
 | ||||
|   after_create :create_task_list | ||||
|  | ||||
| @ -1,4 +1,6 @@ | ||||
| class User < ActiveRecord::Base | ||||
|   MAX_AVATAR_SIZE_KB = 1024 | ||||
| 
 | ||||
|   acts_as_loggable | ||||
|   # Include default devise modules. Others available are: | ||||
|   # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable | ||||
| @ -8,7 +10,7 @@ class User < ActiveRecord::Base | ||||
|   # Setup accessible (or protected) attributes for your model | ||||
|   attr_accessible :email, :password, :password_confirmation, :remember_me, | ||||
|     :first_name, :last_name, :bike_id, | ||||
|     :user_profiles_attributes, :username | ||||
|     :user_profiles_attributes, :username, :avatar | ||||
| 
 | ||||
|   has_many :transactions, as: :customer | ||||
|   has_many :transaction_logs, through: :transactions, source: :logs | ||||
| @ -20,11 +22,19 @@ class User < ActiveRecord::Base | ||||
| 
 | ||||
|   belongs_to :bike | ||||
| 
 | ||||
|   has_attached_file :avatar, :styles => {:thumb => '100x100>'} | ||||
| 
 | ||||
|   default_scope order('username ASC') | ||||
| 
 | ||||
|   validates :username, :presence => true, uniqueness: true | ||||
|   validates :first_name, :presence => true | ||||
|   validates :last_name, :presence => true | ||||
| 
 | ||||
|   validates_attachment :avatar, :content_type => {:content_type => %w{ image/jpeg image/gif image/png }}, | ||||
|                                 :file_name => {:matches => [/png\Z/, /jpe?g\Z/, /gif\Z/]}, | ||||
|                                 :size => {:in => 0..MAX_AVATAR_SIZE_KB.kilobytes} | ||||
| 
 | ||||
| 
 | ||||
|   def to_s | ||||
|     "#{first_name} #{last_name}" | ||||
|   end | ||||
|  | ||||
| @ -4,70 +4,77 @@ | ||||
| 
 | ||||
| .row | ||||
|   .col-xs-12.col-sm-6.col-lg-4 | ||||
|     %fieldset | ||||
|       .form-group | ||||
|         = number_field_tag nil, nil, id: 'shop_id', placeholder: 'Shop ID', min: 0, class: 'form-control' | ||||
|         .help-block | ||||
|     = form_for @bike, as: 'bikes', index: '', url: api_create_bike_path, method: :post, enctype: 'multipart/form-data', html: {id: 'add_bike_form'} do |f| | ||||
|       = f.hidden_field 'bike_purpose_id' | ||||
|       %fieldset | ||||
|         .form-group | ||||
|           = f.number_field 'shop_id', placeholder: 'Shop ID', min: 0, class: 'form-control', id: 'shop_id' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         = select_tag :bike_brand_id, options_for_select(@brands), class: 'form-control' | ||||
|         .help-block | ||||
|         .form-group | ||||
|           = f.select 'bike_brand_id', options_for_select(@brands), {}, class: 'form-control', id: 'bike_brand_id' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         = text_field_tag nil, nil, id: 'model', placeholder: 'Model', class: 'form-control' | ||||
|         .help-block | ||||
|         .form-group | ||||
|           = f.text_field 'model', placeholder: 'Model', class: 'form-control', id: 'model' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         = text_field_tag nil, nil, id: 'serial_number', placeholder: 'Serial Number', class: 'form-control' | ||||
|         .help-block | ||||
|         .form-group | ||||
|           = f.text_field 'serial_number', placeholder: 'Serial Number', class: 'form-control', id: 'serial_number' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         .btn-group(data-toggle="buttons") | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_style', 3 | ||||
|             RD | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_style', 1 | ||||
|             MTN | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_style', 2 | ||||
|             HYB | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_style', 4 | ||||
|             OTHER | ||||
|         = hidden_field_tag nil, nil, id: 'bike_style_id' | ||||
|         .help-block | ||||
|         .form-group | ||||
|           .btn-group(data-toggle="buttons") | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_style_id', 3 | ||||
|               RD | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_style_id', 1 | ||||
|               MTN | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_style_id', 2 | ||||
|               HYB | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_style_id', 4 | ||||
|               OTHER | ||||
|           = hidden_field_tag nil, nil, id: 'bike_style_id' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         = select_tag :bike_wheel_size_id, options_for_select(@wheel_sizes), id: :bike_wheel_size_id, class: 'form-control' | ||||
|         .help-block | ||||
|         .form-group | ||||
|           = f.select 'bike_wheel_size_id', options_for_select(@wheel_sizes), {}, class: 'form-control', id: 'bike_wheel_size_id' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         .btn-group(data-toggle="buttons") | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_condition', 2 | ||||
|             Poor | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_condition', 3 | ||||
|             Fair | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_condition', 4 | ||||
|             Good | ||||
|           %label.btn.btn-default | ||||
|             = radio_button_tag 'bike_condition', 5 | ||||
|             Excellent | ||||
|         = hidden_field_tag nil, nil, id: 'bike_condition_id' | ||||
|         .help-block | ||||
|         .form-group | ||||
|           .btn-group(data-toggle="buttons") | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_condition_id', 2 | ||||
|               Poor | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_condition_id', 3 | ||||
|               Fair | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_condition_id', 4 | ||||
|               Good | ||||
|             %label.btn.btn-default | ||||
|               = f.radio_button 'bike_condition_id', 5 | ||||
|               Excellent | ||||
|           = hidden_field_tag nil, nil, id: 'bike_condition_id' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         .input-group | ||||
|           = number_field_tag nil, nil, id: 'seat_tube_height', placeholder: 'Seat Tube', min: 0, max: 100, class: 'form-control' | ||||
|           .input-group-addon cm | ||||
|         .help-block | ||||
|         .form-group | ||||
|           .input-group | ||||
|             = f.number_field 'seat_tube_height', placeholder: 'Seat Tube', min: 0, max: 100, class: 'form-control', id: 'seat_tube_height' | ||||
|             .input-group-addon cm | ||||
|           .help-block | ||||
| 
 | ||||
|       -# Commenting this out until description is added to Bike | ||||
|         /.form-group | ||||
|           %input{id: "bike_description", placeholder: "Short description", type: "text", class: "input-lg" } | ||||
|         .form-group | ||||
|           %label Bike photo (optional) | ||||
|           = f.file_field 'photo', id: 'photo' | ||||
|           .help-block | ||||
| 
 | ||||
|       .form-group | ||||
|         = button_tag 'Add Bike', id: 'add_bike_submit', class: 'btn btn-primary', data: {url: api_create_bike_path} | ||||
|         -# Commenting this out until description is added to Bike | ||||
|           /.form-group | ||||
|             %input{id: "bike_description", placeholder: "Short description", type: "text", class: "input-lg" } | ||||
| 
 | ||||
|         .form-group | ||||
|           = button_tag 'Add Bike', class: 'btn btn-primary' | ||||
| @ -9,34 +9,49 @@ | ||||
| %h1 #{@bike.shop_id}: #{@bike.bike_brand} | ||||
| %h4= @bike.model | ||||
| 
 | ||||
| %dl.dl-horizontal | ||||
|   %dt Type | ||||
|   %dd= @bike.bike_style | ||||
| .form-horizontal | ||||
|   - if @bike.photo? | ||||
|     .form-group | ||||
|       %label.col-sm-2.control-label Photo | ||||
|       .col-sm-10 | ||||
|         = link_to @bike.photo.url, target: '_blank' do | ||||
|           %img{src: @bike.photo.url(:thumb),  class: 'img-thumbnail'} | ||||
| 
 | ||||
|   %dt Wheel Size | ||||
|   %dd= @bike.bike_wheel_size.display_string | ||||
|   .form-group | ||||
|     %label.col-sm-2.control-label Type | ||||
|     .col-sm-10.form-control-static= @bike.bike_style | ||||
| 
 | ||||
|   %dt Condition | ||||
|   %dd= @bike.bike_condition | ||||
|   .form-group | ||||
|     %label.col-sm-2.control-label Wheel Size | ||||
|     .col-sm-10.form-control-static= @bike.bike_wheel_size.display_string | ||||
| 
 | ||||
|   %dt Seat Tube (cm) | ||||
|   %dd= @bike.seat_tube_height | ||||
|   .form-group | ||||
|     %label.col-sm-2.control-label Condition | ||||
|     .col-sm-10.form-control-static= @bike.bike_condition | ||||
| 
 | ||||
|   %dt Purpose | ||||
|   %dd= @bike.bike_purpose | ||||
|   .form-group | ||||
|     %label.col-sm-2.control-label Seat Tube (cm) | ||||
|     .col-sm-10.form-control-static= @bike.seat_tube_height | ||||
| 
 | ||||
|   .form-group | ||||
|     %label.col-sm-2.control-label Purpose | ||||
|     .col-sm-10.form-control-static= @bike.bike_purpose | ||||
| 
 | ||||
|   - unless @bike.value.nil? | ||||
|     %dt Value | ||||
|     %dd= @bike.value | ||||
|     .form-group | ||||
|       %label.col-sm-2.control-label Value | ||||
|       .col-sm-10.form-control-static= @bike.value | ||||
| 
 | ||||
|   - unless @bike.color.nil? | ||||
|     %dt Color | ||||
|     %dd | ||||
|       .bike-color(style="background-color: ##{@bike.color}")= @bike.color | ||||
|     .form-group | ||||
|       %label.col-sm-2.control-label Color | ||||
|       .col-sm-10.form-control-static | ||||
|         .bike-color(style="background-color: ##{@bike.color}")= @bike.color | ||||
| 
 | ||||
|   - if @task_list | ||||
|     - tasks = @task_list.tasks.to_a | ||||
|     %dt Task list | ||||
|     %dd | ||||
|       = link_to edit_task_list_path(@task_list.id) do | ||||
|         #{tasks.select(&:done).count}/#{tasks.count} | ||||
|     .form-group | ||||
|       %label.col-sm-2.control-label Task list | ||||
|       .col-sm-10.form-control-static | ||||
|         = link_to edit_task_list_path(@task_list.id) do | ||||
|           #{tasks.select(&:done).count}/#{tasks.count} | ||||
| @ -7,13 +7,16 @@ | ||||
| 
 | ||||
|       %fieldset | ||||
|         .form-group | ||||
|           = f.text_field :username, placeholder: 'Username', class: 'form-control' | ||||
|           = f.text_field :username, placeholder: 'Username', class: 'form-control', required: true | ||||
|           .help-block | ||||
| 
 | ||||
|         .form-group | ||||
|           = f.text_field :first_name, placeholder: 'First Name', class: 'form-control' | ||||
|           = f.text_field :first_name, placeholder: 'First Name', class: 'form-control', required: true | ||||
|           .help-block | ||||
| 
 | ||||
|         .form-group | ||||
|           = f.text_field :last_name, placeholder: 'Last Name', class: 'form-control' | ||||
|           = f.text_field :last_name, placeholder: 'Last Name', class: 'form-control', required: true | ||||
|           .help-block | ||||
| 
 | ||||
|         .form-group | ||||
|           = f.email_field :email, placeholder: 'E-mail', class: 'form-control' | ||||
| @ -25,10 +28,18 @@ | ||||
| 
 | ||||
|       %fieldset | ||||
|         .form-group | ||||
|           = f.password_field :password, placeholder: 'Password', class: 'form-control' | ||||
|           %label You may upload your photo to be used as an avatar | ||||
|           = f.file_field :avatar | ||||
|           .help-block #{User::MAX_AVATAR_SIZE_KB} Kb max | ||||
| 
 | ||||
|       %fieldset | ||||
|         .form-group | ||||
|           = f.password_field :password, placeholder: 'Password', class: 'form-control', required: true | ||||
|           .help-block | ||||
| 
 | ||||
|         .form-group | ||||
|           = f.password_field :password_confirmation, placeholder: 'Password Confirmation', class: 'form-control' | ||||
|           = f.password_field :password_confirmation, placeholder: 'Password Confirmation', class: 'form-control', required: true | ||||
|           .help-block | ||||
| 
 | ||||
|         .form-group | ||||
|           = f.submit 'Sign up', class: 'btn btn-primary' | ||||
|  | ||||
| @ -8,6 +8,10 @@ | ||||
| 
 | ||||
| %h4= @task_list.item.model | ||||
| 
 | ||||
| - if @task_list.item.photo? | ||||
|   %p | ||||
|     %img{src: @task_list.item.photo.url(:thumb),  class: 'img-thumbnail'} | ||||
| 
 | ||||
| %fieldset | ||||
|   .form-group | ||||
|     - @task_list.tasks.each do |task| | ||||
|  | ||||
							
								
								
									
										11
									
								
								db/migrate/20170118110330_add_attachment_avatar_to_users.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								db/migrate/20170118110330_add_attachment_avatar_to_users.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| class AddAttachmentAvatarToUsers < ActiveRecord::Migration | ||||
|   def self.up | ||||
|     change_table :users do |t| | ||||
|       t.attachment :avatar | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def self.down | ||||
|     remove_attachment :users, :avatar | ||||
|   end | ||||
| end | ||||
							
								
								
									
										11
									
								
								db/migrate/20170118112258_add_attachment_photo_to_bikes.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								db/migrate/20170118112258_add_attachment_photo_to_bikes.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| class AddAttachmentPhotoToBikes < ActiveRecord::Migration | ||||
|   def self.up | ||||
|     change_table :bikes do |t| | ||||
|       t.attachment :photo | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def self.down | ||||
|     remove_attachment :bikes, :photo | ||||
|   end | ||||
| end | ||||
							
								
								
									
										10
									
								
								db/schema.rb
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								db/schema.rb
									
									
									
									
									
								
							| @ -11,7 +11,7 @@ | ||||
| # | ||||
| # It's strongly recommended to check this file into your version control system. | ||||
| 
 | ||||
| ActiveRecord::Schema.define(:version => 20131019170248) do | ||||
| ActiveRecord::Schema.define(:version => 20170118112258) do | ||||
| 
 | ||||
|   create_table "bike_actions", :force => true do |t| | ||||
|     t.string   "action",     :limit => 128, :null => false | ||||
| @ -73,6 +73,10 @@ ActiveRecord::Schema.define(:version => 20131019170248) do | ||||
|     t.string   "model" | ||||
|     t.integer  "shop_id" | ||||
|     t.integer  "bike_wheel_size_id" | ||||
|     t.string   "photo_file_name" | ||||
|     t.string   "photo_content_type" | ||||
|     t.integer  "photo_file_size" | ||||
|     t.datetime "photo_updated_at" | ||||
|   end | ||||
| 
 | ||||
|   create_table "credit_conversions", :force => true do |t| | ||||
| @ -198,6 +202,10 @@ ActiveRecord::Schema.define(:version => 20131019170248) do | ||||
|     t.string   "first_name",             :default => "", :null => false | ||||
|     t.string   "last_name",              :default => "", :null => false | ||||
|     t.string   "username" | ||||
|     t.string   "avatar_file_name" | ||||
|     t.string   "avatar_content_type" | ||||
|     t.integer  "avatar_file_size" | ||||
|     t.datetime "avatar_updated_at" | ||||
|   end | ||||
| 
 | ||||
|   add_index "users", ["bike_id"], :name => "index_users_on_bike_id", :unique => true | ||||
|  | ||||
							
								
								
									
										1277
									
								
								vendor/assets/javascripts/jquery.form.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1277
									
								
								vendor/assets/javascripts/jquery.form.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user