├── log └── .gitkeep ├── lib ├── tasks │ └── .gitkeep └── assets │ └── .gitkeep ├── app ├── mailers │ └── .gitkeep ├── models │ ├── .gitkeep │ ├── stock.rb │ └── food.rb ├── views │ ├── stocks │ │ ├── show.html.erb │ │ ├── new.html.erb │ │ ├── index.html.erb │ │ └── _form.html.erb │ ├── foods │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ ├── show.html.erb │ │ └── _form.html.erb │ ├── layouts │ │ ├── _shim.html.erb │ │ ├── _header.html.erb │ │ └── application.html.erb │ ├── shared │ │ └── _error_messages.html.erb │ └── static_pages │ │ └── home.html.erb ├── helpers │ ├── foods_helper.rb │ ├── stocks_helper.rb │ └── application_helper.rb ├── .DS_Store ├── assets │ ├── .DS_Store │ ├── images │ │ ├── .DS_Store │ │ ├── dish.png │ │ ├── logo.png │ │ ├── fridge_logo.png │ │ ├── gray_jean.png │ │ ├── tupperware.png │ │ ├── blue_pattern.png │ │ └── grocery_list.png │ ├── javascripts │ │ ├── foods.js │ │ └── application.js │ └── stylesheets │ │ ├── application.css │ │ ├── custom.css.scss │ │ └── m-buttons.css └── controllers │ ├── application_controller.rb │ ├── static_pages_controller.rb │ ├── foods_controller.rb │ └── stocks_controller.rb ├── vendor ├── plugins │ └── .gitkeep └── assets │ ├── javascripts │ └── .gitkeep │ └── stylesheets │ └── .gitkeep ├── .rspec ├── .DS_Store ├── public ├── .DS_Store ├── favicon.ico ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── README.md ├── config ├── routes.rb ├── environment.rb ├── boot.rb ├── initializers │ ├── mime_types.rb │ ├── backtrace_silencers.rb │ ├── session_store.rb │ ├── secret_token.rb │ ├── wrap_parameters.rb │ └── inflections.rb ├── locales │ └── en.yml ├── database.yml ├── environments │ ├── development.rb │ ├── test.rb │ └── production.rb └── application.rb ├── config.ru ├── db ├── migrate │ ├── 20130213060904_add_index_to_foods_name.rb │ ├── 20130213055613_create_foods.rb │ └── 20130213064609_create_stocks.rb ├── seeds.rb └── schema.rb ├── doc └── README_FOR_APP ├── Rakefile ├── script └── rails ├── .gitignore ├── spec ├── requests │ └── static_pages_spec.rb ├── models │ ├── stock_spec.rb │ └── food_spec.rb └── spec_helper.rb ├── Gemfile ├── Guardfile └── Gemfile.lock /log/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --colour 2 | --drb -------------------------------------------------------------------------------- /vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/stocks/show.html.erb: -------------------------------------------------------------------------------- 1 | show.html.erb -------------------------------------------------------------------------------- /app/helpers/foods_helper.rb: -------------------------------------------------------------------------------- 1 | module FoodsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/stocks_helper.rb: -------------------------------------------------------------------------------- 1 | module StocksHelper 2 | end 3 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/.DS_Store -------------------------------------------------------------------------------- /app/views/foods/new.html.erb: -------------------------------------------------------------------------------- 1 |

Foods#new

2 | <%= render "form" %> 3 | -------------------------------------------------------------------------------- /app/views/stocks/new.html.erb: -------------------------------------------------------------------------------- 1 |

Stocks#new

2 | <%= render "form" %> 3 | -------------------------------------------------------------------------------- /app/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/.DS_Store -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/public/.DS_Store -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/public/favicon.ico -------------------------------------------------------------------------------- /app/assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/.DS_Store -------------------------------------------------------------------------------- /app/views/foods/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Foods#edit

2 |

Find me in app/views/foods/edit.html.erb

3 | -------------------------------------------------------------------------------- /app/views/foods/index.html.erb: -------------------------------------------------------------------------------- 1 |

Foods#index

2 |

Find me in app/views/foods/index.html.erb

3 | -------------------------------------------------------------------------------- /app/views/foods/show.html.erb: -------------------------------------------------------------------------------- 1 |

Foods#show

2 |

Find me in app/views/foods/show.html.erb

3 | -------------------------------------------------------------------------------- /app/assets/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/.DS_Store -------------------------------------------------------------------------------- /app/assets/images/dish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/dish.png -------------------------------------------------------------------------------- /app/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/logo.png -------------------------------------------------------------------------------- /app/assets/images/fridge_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/fridge_logo.png -------------------------------------------------------------------------------- /app/assets/images/gray_jean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/gray_jean.png -------------------------------------------------------------------------------- /app/assets/images/tupperware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/tupperware.png -------------------------------------------------------------------------------- /app/assets/images/blue_pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/blue_pattern.png -------------------------------------------------------------------------------- /app/assets/images/grocery_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diasks2/fridgechart/master/app/assets/images/grocery_list.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## FridgeChart 2 | 3 | "Never let food spoil again!" 4 | 5 | bundle exec guard 6 | 7 | bundle exec rake db:test:prepare -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /app/views/layouts/_shim.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Fridgechart::Application.routes.draw do 2 | resources :stocks 3 | resources :foods 4 | root to: 'static_pages#home' 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/static_pages_controller.rb: -------------------------------------------------------------------------------- 1 | class StaticPagesController < ApplicationController 2 | def home 3 | @stocks = Stock.order("expiration").all 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/foods.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | $('.food-type-select').select2({ 3 | placeholder: 'Choose a Category', 4 | allowClear: true 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Fridgechart::Application 5 | -------------------------------------------------------------------------------- /db/migrate/20130213060904_add_index_to_foods_name.rb: -------------------------------------------------------------------------------- 1 | class AddIndexToFoodsName < ActiveRecord::Migration 2 | def change 3 | add_index :foods, :name, unique: true 4 | end 5 | end -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Fridgechart::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /app/models/stock.rb: -------------------------------------------------------------------------------- 1 | class Stock < ActiveRecord::Base 2 | attr_accessible :expiration, :food_id, :quantity 3 | belongs_to :food 4 | 5 | validates :food_id, presence: true 6 | validates :expiration, presence: true 7 | validates :quantity, presence: true 8 | end 9 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | 3 | def full_title(page_title) 4 | base_title = "FridgeChart" 5 | if page_title.empty? 6 | base_title 7 | else 8 | "#{base_title} | #{page_title}" 9 | end 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20130213055613_create_foods.rb: -------------------------------------------------------------------------------- 1 | class CreateFoods < ActiveRecord::Migration 2 | def change 3 | create_table :foods do |t| 4 | t.string :name 5 | t.string :food_type 6 | t.string :lcd_unit 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20130213064609_create_stocks.rb: -------------------------------------------------------------------------------- 1 | class CreateStocks < ActiveRecord::Migration 2 | def change 3 | create_table :stocks do |t| 4 | t.integer :food_id 5 | t.datetime :expiration 6 | t.integer :quantity 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Fridgechart::Application.load_tasks 8 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /app/views/shared/_error_messages.html.erb: -------------------------------------------------------------------------------- 1 | <% if object.errors.any? %> 2 |
3 | The form contains <%= pluralize(object.errors.count, "error") %>. 4 | 9 |
10 | <% end %> -------------------------------------------------------------------------------- /app/views/stocks/index.html.erb: -------------------------------------------------------------------------------- 1 |

Stocks#index

2 | <% @stocks.each do |stock| %> 3 | 9 | <% end %> 10 | -------------------------------------------------------------------------------- /app/models/food.rb: -------------------------------------------------------------------------------- 1 | class Food < ActiveRecord::Base 2 | attr_accessible :food_type, :lcd_unit, :name 3 | has_many :stocks, dependent: :destroy 4 | 5 | before_save { |food| food.name = name.downcase } 6 | validates :name, presence: true, uniqueness: { case_sensitive: false } 7 | validates :food_type, presence: true 8 | validates :lcd_unit, presence: true 9 | end 10 | -------------------------------------------------------------------------------- /app/views/layouts/_header.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Fridgechart::Application.config.session_store :cookie_store, key: '_fridgechart_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Fridgechart::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile ~/.gitignore_global 6 | 7 | # Ignore bundler config 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/*.log 15 | /tmp 16 | -------------------------------------------------------------------------------- /spec/requests/static_pages_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "Static pages" do 4 | 5 | describe "Home page" do 6 | 7 | it "should have the h1 'FridgeChart'" do 8 | visit root_path 9 | page.should have_selector('h1', :text => 'FridgeChart') 10 | end 11 | 12 | it "should have the title 'FridgeChart'" do 13 | visit root_path 14 | page.should have_selector('title', 15 | :text => "FridgeChart | Home") 16 | end 17 | end 18 | end -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Fridgechart::Application.config.secret_token = '8d2882bdca28a1ea7302e59296317b2859702dbb0d20d250724ba69728781a93ae589ea1e608e12a91b419d3981ad75d1c94ace1216a67f2a2c0c429f5785f3c' 8 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /app/views/stocks/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for @stock do |f| %> 2 | <%= render 'shared/error_messages', object: f.object %> 3 |
4 | <%= f.label :food_id %> 5 | <%= f.collection_select :food_id, Food.all, :id, :name %> 6 | <%= f.label :expiration %> 7 | <%= f.text_field :expiration, :class => 'datepicker' %> 8 | 9 | <%= f.label :quantity %> 10 | <%= f.text_field :quantity %> 11 |
12 | <%= f.submit 'Submit', :class => 'btn btn-primary' %> 13 | <% end %> 14 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require select2 13 | *= require bootstrap-datepicker 14 | *= require_tree . 15 | */ 16 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= full_title(yield(:title)) %> 5 | <%= stylesheet_link_tag "application", :media => "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tags %> 8 | <%= render 'layouts/shim' %> 9 | 10 | 11 | 12 | 13 | <%= render 'layouts/header' %> 14 | <% flash.each do |key, value| %> 15 |
<%= value %>
16 | <% end %> 17 | <%= yield %> 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require bootstrap 16 | //= require bootstrap-datepicker 17 | //= require select2 18 | //= require_tree . 19 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /spec/models/stock_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Stock do 4 | 5 | before do 6 | @stock = Stock.new(food_id: 1, expiration: "2013-02-13 07:21:40.423921", quantity: 5) 7 | end 8 | 9 | subject { @stock } 10 | 11 | it { should respond_to(:food_id) } 12 | it { should respond_to(:expiration) } 13 | it { should respond_to(:quantity) } 14 | 15 | it { should be_valid } 16 | 17 | describe "when food_id is not present" do 18 | before { @stock.food_id = nil } 19 | it { should_not be_valid } 20 | end 21 | 22 | describe "when expiration is not present" do 23 | before { @stock.expiration = " " } 24 | it { should_not be_valid } 25 | end 26 | 27 | describe "when quantity is not present" do 28 | before { @stock.quantity = " " } 29 | it { should_not be_valid } 30 | end 31 | end -------------------------------------------------------------------------------- /app/views/foods/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for @food do |f| %> 2 | <%= render 'shared/error_messages', object: f.object %> 3 |
4 | <%= f.label :name %> 5 | <%= f.text_field :name %> 6 | 7 | <%= f.label :food_type %> 8 | <%= f.select :food_type, options_for_select([[], ['Bread, Cereal, Rice and Pasta', 'Bread, Cereal, Rice and Pasta'], ['Dairy', 'Dairy'], ['Fresh Produce', 'Fresh Produce'], ['Frozen Foods', 'Frozen Foods'], ['Health and Beauty', 'Health and Beauty'], ['Household', 'Household'], ['Meat', 'Meat'], ['Staples', 'Staples'], ['Miscellaneous Foods', 'Miscellaneous Foods']], :selected => f.object.food_type), {}, {:class => "food-type-select"} %> 9 | 10 | <%= f.label :lcd_unit %> 11 | <%= f.text_field :lcd_unit %> 12 |
13 | <%= f.submit "Submit", :class => 'btn btn-primary' %> 14 | <% end %> -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rails', '3.2.12' 4 | 5 | group :development, :test do 6 | gem 'sqlite3', '1.3.5' 7 | gem 'rspec-rails', '2.11.0' 8 | gem 'guard-rspec', '1.2.1' 9 | gem 'guard-spork', '1.2.0' 10 | gem 'spork', '0.9.2' 11 | end 12 | 13 | # Gems used only for assets and not required 14 | # in production environments by default. 15 | group :assets do 16 | gem 'sass-rails', '3.2.5' 17 | gem 'coffee-rails', '3.2.2' 18 | gem 'uglifier', '1.2.3' 19 | gem 'bootstrap-sass', '~> 2.3.0.0' 20 | gem 'bootstrap-datepicker-rails' 21 | gem 'select2-rails' 22 | end 23 | 24 | gem 'jquery-rails', '2.0.2' 25 | 26 | group :test do 27 | gem 'capybara', '1.1.2' 28 | gem 'rb-fsevent', '0.9.1', :require => false 29 | gem 'growl', '1.0.3' 30 | end 31 | 32 | group :production do 33 | gem 'pg', '0.12.2' 34 | end -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /app/assets/stylesheets/custom.css.scss: -------------------------------------------------------------------------------- 1 | @import "bootstrap"; 2 | 3 | $fridgeblue: #2480de; 4 | 5 | h1 { 6 | color: $fridgeblue; 7 | font-family: 'Open Sans', sans-serif; 8 | } 9 | 10 | h3 { 11 | font-family: 'Open Sans', sans-serif; 12 | } 13 | 14 | .center { 15 | text-align:center; 16 | } 17 | 18 | .top_banner { 19 | background: url('/assets/gray_jean.png') repeat; 20 | height: 300px; 21 | } 22 | 23 | .navbar .brand { 24 | padding: 6px 20px 0px; 25 | } 26 | 27 | .nav li a { 28 | font-family: 'Open Sans', sans-serif; 29 | } 30 | 31 | .nav li { 32 | padding-top: 3px; 33 | } 34 | 35 | .nav > li.active { 36 | border-top: 3px solid #fff; 37 | padding-top: 0px; 38 | } 39 | 40 | #lower_banner { 41 | padding-top: 30px; 42 | } 43 | 44 | #top_slogan { 45 | margin-top: 50px; 46 | } 47 | 48 | #home_demo_button { 49 | margin-top:25px; 50 | } -------------------------------------------------------------------------------- /app/controllers/foods_controller.rb: -------------------------------------------------------------------------------- 1 | class FoodsController < ApplicationController 2 | def new 3 | @food = Food.new 4 | end 5 | 6 | def create 7 | @food = Food.new(params[:food]) 8 | if @food.save 9 | redirect_to @food, notice: "Created New Food!" 10 | else 11 | render :new 12 | end 13 | end 14 | 15 | def edit 16 | @food = Food.find(params[:id]) 17 | end 18 | 19 | def update 20 | @food = Food.find(params[:id]) 21 | if @food.update_attributes(params[:food]) 22 | redirect_to @food, notice: "Updated Food!" 23 | else 24 | render 'edit' 25 | end 26 | end 27 | 28 | def show 29 | @food = Food.find(params[:id]) 30 | end 31 | 32 | def index 33 | @foods = Food.order("id").all 34 | end 35 | 36 | def destroy 37 | @food = Food.find(params[:id]) 38 | @food.destroy 39 | redirect_to foods_path, notice: "Deleted Food!" 40 | end 41 | 42 | end 43 | -------------------------------------------------------------------------------- /app/controllers/stocks_controller.rb: -------------------------------------------------------------------------------- 1 | class StocksController < ApplicationController 2 | def new 3 | @stock = Stock.new 4 | end 5 | 6 | def create 7 | @stock = Stock.new(params[:stock]) 8 | if @stock.save 9 | redirect_to @stock, notice: "Created New Stock!" 10 | else 11 | render :new 12 | end 13 | end 14 | 15 | def edit 16 | @stock = Stock.find(params[:id]) 17 | end 18 | 19 | def update 20 | @stock = Stock.find(params[:id]) 21 | if @stock.update_attributes(params[:stock]) 22 | redirect_to @stock, notice: "Updated Stock!" 23 | else 24 | render 'edit' 25 | end 26 | end 27 | 28 | def show 29 | @stock = Stock.find(params[:id]) 30 | end 31 | 32 | def index 33 | @stocks = Stock.order("id").all 34 | end 35 | 36 | def destroy 37 | @stock = Stock.find(params[:id]) 38 | @stock.destroy 39 | redirect_to stocks_path, notice: "Deleted Stock!" 40 | end 41 | 42 | end 43 | -------------------------------------------------------------------------------- /spec/models/food_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Food do 4 | 5 | before do 6 | @food = Food.new(name: "Apple", food_type: "Produce", lcd_unit: "Apple") 7 | end 8 | 9 | subject { @food } 10 | 11 | it { should respond_to(:name) } 12 | it { should respond_to(:food_type) } 13 | it { should respond_to(:lcd_unit) } 14 | 15 | it { should be_valid } 16 | 17 | describe "when name is not present" do 18 | before { @food.name = " " } 19 | it { should_not be_valid } 20 | end 21 | 22 | describe "when food_type is not present" do 23 | before { @food.food_type = " " } 24 | it { should_not be_valid } 25 | end 26 | 27 | describe "when lcd_unit is not present" do 28 | before { @food.lcd_unit = " " } 29 | it { should_not be_valid } 30 | end 31 | 32 | describe "when name is already taken" do 33 | before do 34 | food_with_same_name = @food.dup 35 | food_with_same_name.name = @food.name.upcase 36 | food_with_same_name.save 37 | end 38 | 39 | it { should_not be_valid } 40 | end 41 | 42 | end -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20130213064609) do 15 | 16 | create_table "foods", :force => true do |t| 17 | t.string "name" 18 | t.string "food_type" 19 | t.string "lcd_unit" 20 | t.datetime "created_at", :null => false 21 | t.datetime "updated_at", :null => false 22 | end 23 | 24 | add_index "foods", ["name"], :name => "index_foods_on_name", :unique => true 25 | 26 | create_table "stocks", :force => true do |t| 27 | t.integer "food_id" 28 | t.datetime "expiration" 29 | t.integer "quantity" 30 | t.datetime "created_at", :null => false 31 | t.datetime "updated_at", :null => false 32 | end 33 | 34 | end 35 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Fridgechart::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Raise exception on mass assignment protection for Active Record models 26 | config.active_record.mass_assignment_sanitizer = :strict 27 | 28 | # Log the query plan for queries taking more than this (works 29 | # with SQLite, MySQL, and PostgreSQL) 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 31 | 32 | # Do not compress assets 33 | config.assets.compress = false 34 | 35 | # Expands the lines which load the assets 36 | config.assets.debug = true 37 | end 38 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Fridgechart::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # A sample Guardfile 2 | # More info at https://github.com/guard/guard#readme 3 | 4 | require 'active_support/core_ext' 5 | 6 | guard 'spork', :rspec_env => { 'RAILS_ENV' => 'test' } do 7 | watch('config/application.rb') 8 | watch('config/environment.rb') 9 | watch(%r{^config/environments/.+\.rb$}) 10 | watch(%r{^config/initializers/.+\.rb$}) 11 | watch('Gemfile') 12 | watch('Gemfile.lock') 13 | watch('spec/spec_helper.rb') 14 | watch('test/test_helper.rb') 15 | watch('spec/support/') 16 | end 17 | 18 | guard 'rspec', :version => 2, :all_after_pass => false, :cli => '--drb' do 19 | watch(%r{^spec/.+_spec\.rb$}) 20 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } 21 | watch('spec/spec_helper.rb') { "spec" } 22 | 23 | # Rails example 24 | watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 25 | watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } 26 | watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } 27 | watch(%r{^spec/support/(.+)\.rb$}) { "spec" } 28 | watch('config/routes.rb') { "spec/routing" } 29 | watch('app/controllers/application_controller.rb') { "spec/controllers" } 30 | 31 | watch(%r{^app/controllers/(.+)_(controller)\.rb$}) do |m| 32 | ["spec/routing/#{m[1]}_routing_spec.rb", 33 | "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", 34 | "spec/acceptance/#{m[1]}_spec.rb", 35 | (m[1][/_pages/] ? "spec/requests/#{m[1]}_spec.rb" : 36 | "spec/requests/#{m[1].singularize}_pages_spec.rb")] 37 | end 38 | watch(%r{^app/views/(.+)/}) do |m| 39 | (m[1][/_pages/] ? "spec/requests/#{m[1]}_spec.rb" : 40 | "spec/requests/#{m[1].singularize}_pages_spec.rb") 41 | end 42 | 43 | # Capybara request specs 44 | watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" } 45 | 46 | # Turnip features and steps 47 | watch(%r{^spec/acceptance/(.+)\.feature$}) 48 | watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } 49 | end 50 | 51 | 52 | guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do 53 | watch('config/application.rb') 54 | watch('config/environment.rb') 55 | watch('config/environments/test.rb') 56 | watch(%r{^config/initializers/.+\.rb$}) 57 | watch('Gemfile') 58 | watch('Gemfile.lock') 59 | watch('spec/spec_helper.rb') { :rspec } 60 | watch('test/test_helper.rb') { :test_unit } 61 | watch(%r{features/support/}) { :cucumber } 62 | end 63 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Fridgechart::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to nil and saved in location specified by config.assets.prefix 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | # Log the query plan for queries taking more than this (works 65 | # with SQLite, MySQL, and PostgreSQL) 66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 67 | end 68 | -------------------------------------------------------------------------------- /app/views/static_pages/home.html.erb: -------------------------------------------------------------------------------- 1 | <% provide(:title, 'Home') %> 2 |
3 |
4 |

FridgeChart - Never Let Your Food Spoil Again

5 |

Easily track your fridge inventory. Save money. Save Time.

6 |
7 | <%= link_to "Free Demo", root_path, :class => "m-btn red big rnd" %> 8 |
9 |
10 |
11 |
12 |
13 |
14 | <%= image_tag("tupperware.png", :alt => "Reduce Waste") %> 15 |
16 |

Reduces waste by alerting you as to what foods are expiring soon.

17 |
18 |
19 | <%= image_tag("grocery_list.png", :alt => "Automated Grocery Lists") %> 20 |
21 |

Automagically generates your grocery list.

22 |
23 |
24 | <%= image_tag("dish.png", :alt => "Recipes") %> 25 |
26 |

See which ingredients you are missing for your favorite recipes.

27 |
28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | <% @stocks.each do |stock| %> 42 | 43 | 44 | 45 | 59 | 60 | <% end %> 61 | 62 |
FoodQuantityExpires in
<%= link_to stock.food.name, stock %><%= stock.quantity %> 46 | <% case %> 47 | <% when (stock.expiration - Time.now).to_i / 3600 / 24 < 2 && (stock.expiration - Time.now).to_i / 3600 / 24 > 0 %> 48 | <%= distance_of_time_in_words(Time.now, stock.expiration) %> 49 | <% when (stock.expiration - Time.now).to_i / 3600 / 24 < 0 %> 50 | Expired <%= distance_of_time_in_words(Time.now, stock.expiration) %> ago 51 | <% when (stock.expiration - Time.now).to_i / 3600 / 24 < 4 && (stock.expiration - Time.now).to_i / 3600 / 24 >= 2 %> 52 | <%= distance_of_time_in_words(Time.now, stock.expiration) %> 53 | <% else %> 54 | <%= distance_of_time_in_words(Time.now, stock.expiration) %> 55 | <% end %> 56 | <%= %> 57 | 58 |
63 |
64 |
65 |
-------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | # Pick the frameworks you want: 4 | require "active_record/railtie" 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "active_resource/railtie" 8 | require "sprockets/railtie" 9 | # require "rails/test_unit/railtie" 10 | 11 | if defined?(Bundler) 12 | # If you precompile assets before deploying to production, use this line 13 | Bundler.require(*Rails.groups(:assets => %w(development test))) 14 | # If you want your assets lazily compiled in production, use this line 15 | # Bundler.require(:default, :assets, Rails.env) 16 | end 17 | 18 | module Fridgechart 19 | class Application < Rails::Application 20 | # Settings in config/environments/* take precedence over those specified here. 21 | # Application configuration should go into files in config/initializers 22 | # -- all .rb files in that directory are automatically loaded. 23 | 24 | # Custom directories with classes and modules you want to be autoloadable. 25 | # config.autoload_paths += %W(#{config.root}/extras) 26 | 27 | # Only load the plugins named here, in the order given (default is alphabetical). 28 | # :all can be used as a placeholder for all plugins not explicitly named. 29 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 30 | 31 | # Activate observers that should always be running. 32 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 33 | 34 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 35 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 36 | # config.time_zone = 'Central Time (US & Canada)' 37 | 38 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 39 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 40 | # config.i18n.default_locale = :de 41 | 42 | # Configure the default encoding used in templates for Ruby 1.9. 43 | config.encoding = "utf-8" 44 | 45 | # Configure sensitive parameters which will be filtered from the log file. 46 | config.filter_parameters += [:password] 47 | 48 | # Enable escaping HTML in JSON. 49 | config.active_support.escape_html_entities_in_json = true 50 | 51 | # Use SQL instead of Active Record's schema dumper when creating the database. 52 | # This is necessary if your schema can't be completely dumped by the schema dumper, 53 | # like if you have constraints or database-specific column types 54 | # config.active_record.schema_format = :sql 55 | 56 | # Enforce whitelist mode for mass assignment. 57 | # This will create an empty whitelist of attributes available for mass-assignment for all models 58 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 59 | # parameters by using an attr_accessible or attr_protected declaration. 60 | config.active_record.whitelist_attributes = true 61 | 62 | # Enable the asset pipeline 63 | config.assets.enabled = true 64 | 65 | # Version of your assets, change this if you want to expire all your assets 66 | config.assets.version = '1.0' 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'spork' 3 | #uncomment the following line to use spork with the debugger 4 | #require 'spork/ext/ruby-debug' 5 | 6 | Spork.prefork do 7 | # Loading more in this block will cause your tests to run faster. However, 8 | # if you change any configuration or code from libraries loaded here, you'll 9 | # need to restart spork for it take effect. 10 | # This file is copied to spec/ when you run 'rails generate rspec:install' 11 | ENV["RAILS_ENV"] ||= 'test' 12 | require File.expand_path("../../config/environment", __FILE__) 13 | require 'rspec/rails' 14 | require 'rspec/autorun' 15 | 16 | # Requires supporting ruby files with custom matchers and macros, etc, 17 | # in spec/support/ and its subdirectories. 18 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 19 | 20 | RSpec.configure do |config| 21 | # == Mock Framework 22 | # 23 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 24 | # 25 | # config.mock_with :mocha 26 | # config.mock_with :flexmock 27 | # config.mock_with :rr 28 | config.mock_with :rspec 29 | 30 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 31 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 32 | 33 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 34 | # examples within a transaction, remove the following line or assign false 35 | # instead of true. 36 | config.use_transactional_fixtures = true 37 | 38 | # If true, the base class of anonymous controllers will be inferred 39 | # automatically. This will be the default behavior in future versions of 40 | # rspec-rails. 41 | config.infer_base_class_for_anonymous_controllers = false 42 | end 43 | end 44 | 45 | Spork.each_run do 46 | # This code will be run each time you run your specs. 47 | 48 | end 49 | 50 | # --- Instructions --- 51 | # Sort the contents of this file into a Spork.prefork and a Spork.each_run 52 | # block. 53 | # 54 | # The Spork.prefork block is run only once when the spork server is started. 55 | # You typically want to place most of your (slow) initializer code in here, in 56 | # particular, require'ing any 3rd-party gems that you don't normally modify 57 | # during development. 58 | # 59 | # The Spork.each_run block is run each time you run your specs. In case you 60 | # need to load files that tend to change during development, require them here. 61 | # With Rails, your application modules are loaded automatically, so sometimes 62 | # this block can remain empty. 63 | # 64 | # Note: You can modify files loaded *from* the Spork.each_run block without 65 | # restarting the spork server. However, this file itself will not be reloaded, 66 | # so if you change any of the code inside the each_run block, you still need to 67 | # restart the server. In general, if you have non-trivial code in this file, 68 | # it's advisable to move it into a separate file so you can easily edit it 69 | # without restarting spork. (For example, with RSpec, you could move 70 | # non-trivial code into a file spec/support/my_helper.rb, making sure that the 71 | # spec/support/* files are require'd from inside the each_run block.) 72 | # 73 | # Any code that is left outside the two blocks will be run during preforking 74 | # *and* during each_run -- that's probably not what you want. 75 | # 76 | # These instructions should self-destruct in 10 seconds. If they don't, feel 77 | # free to delete them. 78 | 79 | 80 | 81 | 82 | # This file is copied to spec/ when you run 'rails generate rspec:install' 83 | ENV["RAILS_ENV"] ||= 'test' 84 | require File.expand_path("../../config/environment", __FILE__) 85 | require 'rspec/rails' 86 | require 'rspec/autorun' 87 | 88 | # Requires supporting ruby files with custom matchers and macros, etc, 89 | # in spec/support/ and its subdirectories. 90 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 91 | 92 | RSpec.configure do |config| 93 | # ## Mock Framework 94 | # 95 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 96 | # 97 | # config.mock_with :mocha 98 | # config.mock_with :flexmock 99 | # config.mock_with :rr 100 | 101 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 102 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 103 | 104 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 105 | # examples within a transaction, remove the following line or assign false 106 | # instead of true. 107 | config.use_transactional_fixtures = true 108 | 109 | # If true, the base class of anonymous controllers will be inferred 110 | # automatically. This will be the default behavior in future versions of 111 | # rspec-rails. 112 | config.infer_base_class_for_anonymous_controllers = false 113 | 114 | # Run specs in random order to surface order dependencies. If you find an 115 | # order dependency and want to debug it, you can fix the order by providing 116 | # the seed, which is printed after each run. 117 | # --seed 1234 118 | config.order = "random" 119 | end 120 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (3.2.12) 5 | actionpack (= 3.2.12) 6 | mail (~> 2.4.4) 7 | actionpack (3.2.12) 8 | activemodel (= 3.2.12) 9 | activesupport (= 3.2.12) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | journey (~> 1.0.4) 13 | rack (~> 1.4.5) 14 | rack-cache (~> 1.2) 15 | rack-test (~> 0.6.1) 16 | sprockets (~> 2.2.1) 17 | activemodel (3.2.12) 18 | activesupport (= 3.2.12) 19 | builder (~> 3.0.0) 20 | activerecord (3.2.12) 21 | activemodel (= 3.2.12) 22 | activesupport (= 3.2.12) 23 | arel (~> 3.0.2) 24 | tzinfo (~> 0.3.29) 25 | activeresource (3.2.12) 26 | activemodel (= 3.2.12) 27 | activesupport (= 3.2.12) 28 | activesupport (3.2.12) 29 | i18n (~> 0.6) 30 | multi_json (~> 1.0) 31 | arel (3.0.2) 32 | bootstrap-datepicker-rails (0.6.41) 33 | railties (>= 3.0) 34 | bootstrap-sass (2.3.0.0) 35 | sass (~> 3.2) 36 | builder (3.0.4) 37 | capybara (1.1.2) 38 | mime-types (>= 1.16) 39 | nokogiri (>= 1.3.3) 40 | rack (>= 1.0.0) 41 | rack-test (>= 0.5.4) 42 | selenium-webdriver (~> 2.0) 43 | xpath (~> 0.1.4) 44 | childprocess (0.3.8) 45 | ffi (~> 1.0, >= 1.0.11) 46 | coderay (1.0.8) 47 | coffee-rails (3.2.2) 48 | coffee-script (>= 2.2.0) 49 | railties (~> 3.2.0) 50 | coffee-script (2.2.0) 51 | coffee-script-source 52 | execjs 53 | coffee-script-source (1.4.0) 54 | diff-lcs (1.1.3) 55 | erubis (2.7.0) 56 | execjs (1.4.0) 57 | multi_json (~> 1.0) 58 | ffi (1.3.1) 59 | growl (1.0.3) 60 | guard (1.6.2) 61 | listen (>= 0.6.0) 62 | lumberjack (>= 1.0.2) 63 | pry (>= 0.9.10) 64 | terminal-table (>= 1.4.3) 65 | thor (>= 0.14.6) 66 | guard-rspec (1.2.1) 67 | guard (>= 1.1) 68 | guard-spork (1.2.0) 69 | childprocess 70 | guard (>= 1.1) 71 | spork (>= 0.8.4) 72 | sys-proctable 73 | hike (1.2.1) 74 | i18n (0.6.1) 75 | journey (1.0.4) 76 | jquery-rails (2.0.2) 77 | railties (>= 3.2.0, < 5.0) 78 | thor (~> 0.14) 79 | json (1.7.7) 80 | listen (0.7.2) 81 | lumberjack (1.0.2) 82 | mail (2.4.4) 83 | i18n (>= 0.4.0) 84 | mime-types (~> 1.16) 85 | treetop (~> 1.4.8) 86 | method_source (0.8.1) 87 | mime-types (1.21) 88 | multi_json (1.6.1) 89 | nokogiri (1.5.6) 90 | pg (0.12.2) 91 | polyglot (0.3.3) 92 | pry (0.9.12) 93 | coderay (~> 1.0.5) 94 | method_source (~> 0.8) 95 | slop (~> 3.4) 96 | rack (1.4.5) 97 | rack-cache (1.2) 98 | rack (>= 0.4) 99 | rack-ssl (1.3.3) 100 | rack 101 | rack-test (0.6.2) 102 | rack (>= 1.0) 103 | rails (3.2.12) 104 | actionmailer (= 3.2.12) 105 | actionpack (= 3.2.12) 106 | activerecord (= 3.2.12) 107 | activeresource (= 3.2.12) 108 | activesupport (= 3.2.12) 109 | bundler (~> 1.0) 110 | railties (= 3.2.12) 111 | railties (3.2.12) 112 | actionpack (= 3.2.12) 113 | activesupport (= 3.2.12) 114 | rack-ssl (~> 1.3.2) 115 | rake (>= 0.8.7) 116 | rdoc (~> 3.4) 117 | thor (>= 0.14.6, < 2.0) 118 | rake (10.0.3) 119 | rb-fsevent (0.9.1) 120 | rdoc (3.12.1) 121 | json (~> 1.4) 122 | rspec (2.11.0) 123 | rspec-core (~> 2.11.0) 124 | rspec-expectations (~> 2.11.0) 125 | rspec-mocks (~> 2.11.0) 126 | rspec-core (2.11.1) 127 | rspec-expectations (2.11.3) 128 | diff-lcs (~> 1.1.3) 129 | rspec-mocks (2.11.3) 130 | rspec-rails (2.11.0) 131 | actionpack (>= 3.0) 132 | activesupport (>= 3.0) 133 | railties (>= 3.0) 134 | rspec (~> 2.11.0) 135 | rubyzip (0.9.9) 136 | sass (3.2.5) 137 | sass-rails (3.2.5) 138 | railties (~> 3.2.0) 139 | sass (>= 3.1.10) 140 | tilt (~> 1.3) 141 | select2-rails (3.2.1) 142 | thor (~> 0.14) 143 | selenium-webdriver (2.29.0) 144 | childprocess (>= 0.2.5) 145 | multi_json (~> 1.0) 146 | rubyzip 147 | websocket (~> 1.0.4) 148 | slop (3.4.3) 149 | spork (0.9.2) 150 | sprockets (2.2.2) 151 | hike (~> 1.2) 152 | multi_json (~> 1.0) 153 | rack (~> 1.0) 154 | tilt (~> 1.1, != 1.3.0) 155 | sqlite3 (1.3.5) 156 | sys-proctable (0.9.2) 157 | terminal-table (1.4.5) 158 | thor (0.17.0) 159 | tilt (1.3.3) 160 | treetop (1.4.12) 161 | polyglot 162 | polyglot (>= 0.3.1) 163 | tzinfo (0.3.35) 164 | uglifier (1.2.3) 165 | execjs (>= 0.3.0) 166 | multi_json (>= 1.0.2) 167 | websocket (1.0.7) 168 | xpath (0.1.4) 169 | nokogiri (~> 1.3) 170 | 171 | PLATFORMS 172 | ruby 173 | 174 | DEPENDENCIES 175 | bootstrap-datepicker-rails 176 | bootstrap-sass (~> 2.3.0.0) 177 | capybara (= 1.1.2) 178 | coffee-rails (= 3.2.2) 179 | growl (= 1.0.3) 180 | guard-rspec (= 1.2.1) 181 | guard-spork (= 1.2.0) 182 | jquery-rails (= 2.0.2) 183 | pg (= 0.12.2) 184 | rails (= 3.2.12) 185 | rb-fsevent (= 0.9.1) 186 | rspec-rails (= 2.11.0) 187 | sass-rails (= 3.2.5) 188 | select2-rails 189 | spork (= 0.9.2) 190 | sqlite3 (= 1.3.5) 191 | uglifier (= 1.2.3) 192 | -------------------------------------------------------------------------------- /app/assets/stylesheets/m-buttons.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * CSS3 Microsoft Metro Buttons 3 | * Inspired by Tim O'Donnell's CSS3 Google Buttons, Twitter Bootstrap, and Microsoft. Icons from glyphicons.com and Syncfusion's Metro Studio. 4 | * I do not claim ownership on the origin of design and icons. 5 | * Built by Ace Subido (http://github.com/ace-subido) 6 | */ 7 | a:focus { 8 | outline: thin dotted; 9 | outline: 5px auto -webkit-focus-ring-color; 10 | outline-offset: -2px; 11 | } 12 | a:hover, a:active { 13 | outline: 0; 14 | } 15 | button, 16 | input, 17 | select, 18 | textarea { 19 | margin: 0; 20 | font-size: 100%; 21 | /*vertical-align: middle;*/ 22 | 23 | } 24 | button, input { 25 | *overflow: visible; 26 | line-height: normal; 27 | } 28 | button::-moz-focus-inner, input::-moz-focus-inner { 29 | padding: 0; 30 | border: 0; 31 | } 32 | button, 33 | input[type="button"], 34 | input[type="reset"], 35 | input[type="submit"] { 36 | cursor: pointer; 37 | -webkit-appearance: button; 38 | -moz-appearance: none; 39 | } 40 | /* overrides button presets for mozilla clients*/ 41 | @-moz-document url-prefix() { 42 | button, 43 | input[type="button"], 44 | input[type="reset"], 45 | input[type="submit"] { 46 | cursor: pointer; 47 | padding: 6px 14px; 48 | } 49 | } 50 | input[type="search"] { 51 | -webkit-appearance: textfield; 52 | -webkit-box-sizing: content-box; 53 | -moz-box-sizing: content-box; 54 | box-sizing: content-box; 55 | } 56 | input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { 57 | -webkit-appearance: none; 58 | } 59 | .dropdown { 60 | position: relative; 61 | } 62 | .dropdown-toggle { 63 | *margin-bottom: -3px; 64 | } 65 | .dropdown-toggle:active, .open .dropdown-toggle { 66 | outline: 0; 67 | } 68 | 69 | .caret { 70 | display: inline-block; 71 | width: 0; 72 | height: 0; 73 | text-indent: -99999px; 74 | *text-indent: 0; 75 | vertical-align: top; 76 | margin-top: 5px; 77 | margin-left: 2px; 78 | margin-right: 2px; 79 | border-left: 4px solid transparent; 80 | border-right: 4px solid transparent; 81 | border-top: 4px solid black; 82 | opacity: 0.5; 83 | filter: alpha(opacity=50); 84 | content: "\2193"; 85 | } 86 | .caret.white{ 87 | border-left: 4px solid transparent; 88 | border-right: 4px solid transparent; 89 | border-top: 4px solid white; 90 | opacity: 0.95; 91 | filter: alpha(opacity=95); 92 | } 93 | .dropdown .caret { 94 | margin-top: 8px; 95 | margin-left: 2px; 96 | } 97 | 98 | .dropdown:hover .caret, .open.dropdown .caret { 99 | opacity: 1; 100 | filter: alpha(opacity=100); 101 | } 102 | 103 | .m-dropdown-menu { 104 | position: absolute; 105 | top: 98%; 106 | left: 0; 107 | z-index: 1000; 108 | float: left; 109 | display: none; 110 | min-width: 225px; 111 | max-width: 225px; 112 | padding: 0 0 6px 0; 113 | margin: 0 0 0; 114 | list-style: none; 115 | background-color: white; 116 | 117 | -webkit-box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1); 118 | -moz-box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1); 119 | box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1); 120 | 121 | font-size: 14px; 122 | font-family: "Segoe UI",Helvetica, Arial, sans-serif; 123 | 124 | border: 1px solid #eeeeee; 125 | 126 | } 127 | 128 | .m-dropdown-menu.bottom-up { 129 | top: auto; 130 | bottom: 100%; 131 | margin-bottom: 2px; 132 | } 133 | 134 | .m-dropdown-menu .divider { 135 | border-top: 1px solid #ebebeb; 136 | margin-top: 9px; 137 | margin-bottom: 10px; 138 | padding: 0; 139 | cursor: default; 140 | } 141 | .m-dropdown-menu a { 142 | position: relative; 143 | padding: 6px 0 6px 30px; 144 | color: #333; 145 | text-decoration: none; 146 | display: block; 147 | clear: both; 148 | font-weight: normal; 149 | line-height: 18px; 150 | white-space: nowrap; 151 | } 152 | .m-dropdown-menu a [class^="icon-"] { 153 | position: absolute; 154 | left: 7px; 155 | top: 8px; 156 | } 157 | .m-dropdown-menu li > a:hover, .m-dropdown-menu .active > a, .m-dropdown-menu .active > a:hover { 158 | text-decoration: none; 159 | background-color: #eee; 160 | } 161 | .dropdown.open { 162 | *z-index: 1000; 163 | } 164 | .dropdown.open .dropdown-toggle { 165 | color: #08c; 166 | background: #ccc; 167 | background: rgba(0, 0, 0, 0.3); 168 | } 169 | .dropdown.open .m-dropdown-menu { 170 | display: block; 171 | } 172 | 173 | .m-btn { 174 | position: relative; 175 | display: inline-block; 176 | overflow: visible; 177 | margin: 0; 178 | padding: 10px 14px; 179 | margin-top: 8px; 180 | cursor: pointer; 181 | outline: none; 182 | border: none; 183 | background-color: #eeeeee; 184 | background-image: -moz-linear-gradient(top, #eeeeee, #eeeeee); 185 | background-image: -ms-linear-gradient(top, #eeeeee, #eeeeee); 186 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#eeeeee), to(#eeeeee)); 187 | background-image: -webkit-linear-gradient(top, #eeeeee, #eeeeee); 188 | background-image: -o-linear-gradient(top, #eeeeee, #eeeeee); 189 | background-image: linear-gradient(top, #eeeeee, #eeeeee); 190 | background-repeat: repeat-x; 191 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#eeeeee', GradientType=0); 192 | -webkit-background-clip: padding; 193 | -moz-background-clip: padding; 194 | background-clip: padding; 195 | /* IE hacks */ 196 | 197 | zoom: 1; 198 | z-index: 1; 199 | *display: inline; 200 | font-family: "Segoe UI", Helvetica, Arial, sans-serif; 201 | font-size: 14px; 202 | line-height: 14px; 203 | color: #333333; 204 | min-width: 42px; 205 | 206 | text-shadow: #ffffff 0 1px 0; 207 | text-align: center; 208 | text-decoration: none; 209 | white-space: nowrap; 210 | 211 | vertical-align: inherit; 212 | } 213 | .m-btn:hover, 214 | .m-btn:focus, 215 | .m-btn:active, 216 | .m-btn.active { 217 | color: #333; 218 | text-decoration: none; 219 | background-color: #dcdcdc; 220 | background-image: -moz-linear-gradient(top, #dcdcdc, #dcdcdc); 221 | background-image: -ms-linear-gradient(top, #dcdcdc, #dcdcdc); 222 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dcdcdc), to(#dcdcdc)); 223 | background-image: -webkit-linear-gradient(top, #dcdcdc, #dcdcdc); 224 | background-image: -o-linear-gradient(top, #dcdcdc, #dcdcdc); 225 | background-image: linear-gradient(top, #dcdcdc, #dcdcdc); 226 | background-repeat: repeat-x; 227 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dcdcdc', endColorstr='#dcdcdc', GradientType=0); 228 | z-index: 100; 229 | outline: none; 230 | } 231 | .m-btn:active, .m-btn.active { 232 | background-color: #eeeeee; 233 | background-image: -moz-linear-gradient(top, #eeeeee, #dcdcdc); 234 | background-image: -ms-linear-gradient(top, #eeeeee, #dcdcdc); 235 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#eeeeee), to(#dcdcdc)); 236 | background-image: -webkit-linear-gradient(top, #eeeeee, #dcdcdc); 237 | background-image: -o-linear-gradient(top, #eeeeee, #dcdcdc); 238 | background-image: linear-gradient(top, #eeeeee, #dcdcdc); 239 | background-repeat: repeat-x; 240 | -webkit-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); 241 | -moz-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); 242 | box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); 243 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dcdcdc', GradientType=0); 244 | } 245 | .m-btn:focus { 246 | /* Blue border on button focus. */ 247 | border-color: #4D90FE; 248 | } 249 | /* overrides extra padding on button elements in Firefox */ 250 | .m-btn::-moz-focus-inner { 251 | padding: 0; 252 | border: 0; 253 | } 254 | .m-btn.red-stripe 255 | { 256 | border-left: 3px solid #d84a38; 257 | } 258 | 259 | .m-btn.blue-stripe 260 | { 261 | border-left: 3px solid #4d90fe; 262 | } 263 | 264 | .m-btn.purple-stripe 265 | { 266 | border-left: 3px solid #852b99; 267 | } 268 | 269 | .m-btn.green-stripe 270 | { 271 | border-left: 3px solid #35aa47; 272 | } 273 | 274 | /* Common button classes */ 275 | .m-btn.red:active, 276 | .m-btn.red.active, 277 | .m-btn.red.disabled, 278 | .m-btn.red[disabled], 279 | .m-btn.blue:active, 280 | .m-btn.blue.active, 281 | .m-btn.blue.disabled, 282 | .m-btn.blue[disabled], 283 | .m-btn.purple:active, 284 | .m-btn.purple.active, 285 | .m-btn.purple.disabled, 286 | .m-btn.purple[disabled], 287 | .m-btn.green:active, 288 | .m-btn.green.active, 289 | .m-btn.green.disabled, 290 | .m-btn.green[disabled], 291 | .m-btn.black:active, 292 | .m-btn.black.active, 293 | .m-btn.black.disabled, 294 | .m-btn.black[disabled] 295 | { 296 | -webkit-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); 297 | -moz-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); 298 | box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); 299 | color: white !important; 300 | } 301 | .m-btn.red.disabled, 302 | .m-btn.red[disabled], 303 | .m-btn.blue.disabled, 304 | .m-btn.blue[disabled], 305 | .m-btn.purple.disabled, 306 | .m-btn.purple[disabled], 307 | .m-btn.green.disabled, 308 | .m-btn.green[disabled] 309 | { 310 | opacity: .7; 311 | } 312 | 313 | .m-btn.black.disabled, 314 | .m-btn.black[disabled] 315 | { 316 | opacity: .5; 317 | } 318 | 319 | /* Red */ 320 | .m-btn.red { 321 | color: white; 322 | text-shadow: none; 323 | background-color: #d84a38; 324 | background-image: -moz-linear-gradient(top, #dd4b39, #d14836); 325 | background-image: -ms-linear-gradient(top, #dd4b39, #d14836); 326 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dd4b39), to(#d14836)); 327 | background-image: -webkit-linear-gradient(top, #dd4b39, #d14836); 328 | background-image: -o-linear-gradient(top, #dd4b39, #d14836); 329 | background-image: linear-gradient(top, #dd4b39, #d14836); 330 | background-repeat: repeat-x; 331 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dd4b39', endColorstr='#d14836', GradientType=0); 332 | } 333 | .m-btn.red:hover, 334 | .m-btn.red:focus, 335 | .m-btn.red:active, 336 | .m-btn.red.active, 337 | .m-btn.red[disabled], 338 | .m-btn.red.disabled { 339 | background-color: #c53727; 340 | background-image: -moz-linear-gradient(top, #c53727, #c53727); 341 | background-image: -ms-linear-gradient(top, #c53727, #c53727); 342 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#c53727), to(#c53727)); 343 | background-image: -webkit-linear-gradient(top, #c53727, #c53727); 344 | background-image: -o-linear-gradient(top, #c53727, #c53727); 345 | background-image: linear-gradient(top, #c53727, #c53727); 346 | background-repeat: repeat-x; 347 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c53727', endColorstr='#c53727', GradientType=0); 348 | } 349 | 350 | 351 | .m-btn.red:active, 352 | .m-btn.red.active 353 | { 354 | background-color: #dd4b39; 355 | background-image: -moz-linear-gradient(top, #dd4b39, #c53727); 356 | background-image: -ms-linear-gradient(top, #dd4b39, #c53727); 357 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dd4b39), to(#c53727)); 358 | background-image: -webkit-linear-gradient(top, #dd4b39, #c53727); 359 | background-image: -o-lineark-gradient(top, #dd4b39, #c53727); 360 | background-image: linear-gradient(top, #dd4b39, #c53727); 361 | background-repeat: repeat-x; 362 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dd4b39', endColorstr='#c53727', GradientType=0); 363 | 364 | } 365 | 366 | /* Blue */ 367 | .m-btn.blue 368 | { 369 | color: white; 370 | text-shadow: none; 371 | background-color: #4d90fe; 372 | background-image: -moz-linear-gradient(top, #4d90fe, #4787ed); 373 | background-image: -ms-linear-gradient(top, #4d90fe, #4787ed); 374 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#4d90fe), to(#4787ed)); 375 | background-image: -webkit-linear-gradient(top, #4d90fe, #4787ed); 376 | background-image: -o-linear-gradient(top, #4d90fe, #4787ed); 377 | background-image: linear-gradient(top, #4d90fe, #4787ed); 378 | background-repeat: repeat-x; 379 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4d90fe', endColorstr='#4787ed', GradientType=0); 380 | } 381 | .m-btn.blue:hover, 382 | .m-btn.blue:focus, 383 | .m-btn.blue:active, 384 | .m-btn.blue.active, 385 | .m-btn.blue[disabled], 386 | .m-btn.blue.disabled { 387 | background-color: #0072bb; 388 | background-image: -moz-linear-gradient(top, #0072bb, #0072bb); 389 | background-image: -ms-linear-gradient(top, #0072bb, #0072bb); 390 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0072bb), to(#0072bb)); 391 | background-image: -webkit-linear-gradient(top, #0072bb, #0072bb); 392 | background-image: -o-linear-gradient(top, #0072bb, #0072bb); 393 | background-image: linear-gradient(top, #0072bb, #0072bb); 394 | background-repeat: repeat-x; 395 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0072bb', endColorstr='#0072bb', GradientType=0); 396 | } 397 | 398 | .m-btn.blue:active, 399 | .m-btn.blue.active 400 | { 401 | background-color: #4d90fe; 402 | background-image: -moz-linear-gradient(top, #4d90fe, #0072bb); 403 | background-image: -ms-linear-gradient(top, #4d90fe, #0072bb); 404 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#4d90fe), to(#0072bb)); 405 | background-image: -webkit-linear-gradient(top, #4d90fe, #0072bb); 406 | background-image: -o-linear-gradient(top, #4d90fe, #0072bb); 407 | background-image: linear-gradient(top, #4d90fe, #0072bb); 408 | background-repeat: repeat-x; 409 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4d90fe', endColorstr='#0072bb', GradientType=0); 410 | 411 | } 412 | /* Green */ 413 | .m-btn.green { 414 | color: white; 415 | text-shadow: none; 416 | background-color: #35aa47; 417 | background-image: -moz-linear-gradient(top, #35aa47, #35aa47); 418 | background-image: -ms-linear-gradient(top, #35aa47, #35aa47); 419 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#35aa47), to(#35aa47)); 420 | background-image: -webkit-linear-gradient(top, #35aa47, #35aa47); 421 | background-image: -o-linear-gradient(top, #35aa47, #35aa47); 422 | background-image: linear-gradient(top, #35aa47, #35aa47); 423 | background-repeat: repeat-x; 424 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#35aa47', endColorstr='#35aa47', GradientType=0); 425 | } 426 | .m-btn.green:hover, 427 | .m-btn.green:focus, 428 | .m-btn.green:active, 429 | .m-btn.green.active, 430 | .m-btn.green.disabled, 431 | .m-btn.green[disabled]{ 432 | background-color: #1d943b; 433 | background-image: -moz-linear-gradient(top, #1d943b, #1d943b); 434 | background-image: -ms-linear-gradient(top, #1d943b, #1d943b); 435 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#1d943b), to(#1d943b)); 436 | background-image: -webkit-linear-gradient(top, #1d943b, #1d943b); 437 | background-image: -o-linear-gradient(top, #1d943b, #1d943b); 438 | background-image: linear-gradient(top, #1d943b, #1d943b); 439 | background-repeat: repeat-x; 440 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#1d943b', endColorstr='#1d943b', GradientType=0); 441 | } 442 | 443 | .m-btn.green:active, 444 | .m-btn.green.active 445 | { 446 | background-color: #35aa47; 447 | background-image: -moz-linear-gradient(top, #35aa47, #1d943b); 448 | background-image: -ms-linear-gradient(top, #35aa47, #1d943b); 449 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#35aa47), to(#1d943b)); 450 | background-image: -webkit-linear-gradient(top, #35aa47, #1d943b); 451 | background-image: -o-linear-gradient(top, #35aa47, #1d943b); 452 | background-image: linear-gradient(top, #35aa47, #1d943b); 453 | background-repeat: repeat-x; 454 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#35aa47', endColorstr='#1d943b', GradientType=0); 455 | 456 | } 457 | /* Purple */ 458 | .m-btn.purple { 459 | color: white; 460 | text-shadow: none; 461 | background-color: #852b99; 462 | background-image: -moz-linear-gradient(top, #852b99, #852b99); 463 | background-image: -ms-linear-gradient(top, #852b99, #852b99); 464 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#852b99), to(#852b99)); 465 | background-image: -webkit-linear-gradient(top, #852b99, #852b99); 466 | background-image: -o-linear-gradient(top, #852b99, #852b99); 467 | background-image: linear-gradient(top, #852b99, #852b99); 468 | background-repeat: repeat-x; 469 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#852b99', endColorstr='#852b99', GradientType=0); 470 | } 471 | .m-btn.purple:hover, 472 | .m-btn.purple:focus, 473 | .m-btn.purple:active, 474 | .m-btn.purple.active, 475 | .m-btn.purple.disabled, 476 | .m-btn.purple[disabled] { 477 | background-color: #6d1b81; 478 | background-image: -moz-linear-gradient(top, #6d1b81, #6d1b81); 479 | background-image: -ms-linear-gradient(top, #6d1b81, #6d1b81); 480 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#6d1b81), to(#6d1b81)); 481 | background-image: -webkit-linear-gradient(top, #6d1b81, #6d1b81); 482 | background-image: -o-linear-gradient(top, #6d1b81, #6d1b81); 483 | background-image: linear-gradient(top, #6d1b81, #6d1b81); 484 | background-repeat: repeat-x; 485 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#6d1b81', endColorstr='#6d1b81', GradientType=0); 486 | } 487 | 488 | .m-btn.purple:active, 489 | .m-btn.purple.active 490 | { 491 | background-color: #35aa47; 492 | background-image: -moz-linear-gradient(top, #852b99, #6d1b81); 493 | background-image: -ms-linear-gradient(top, #852b99, #6d1b81); 494 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#852b99), to(#6d1b81)); 495 | background-image: -webkit-linear-gradient(top, #852b99, #6d1b81); 496 | background-image: -o-linear-gradient(top, #852b99, #6d1b81); 497 | background-image: linear-gradient(top, #852b99, #6d1b81); 498 | background-repeat: repeat-x; 499 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#852b99', endColorstr='#6d1b81', GradientType=0); 500 | 501 | } 502 | 503 | 504 | .m-btn.black { 505 | color: white; 506 | text-shadow: none; 507 | background-color: #555555; 508 | background-image: -moz-linear-gradient(top, #555555, #555555); 509 | background-image: -ms-linear-gradient(top, #555555, #555555); 510 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#555555)); 511 | background-image: -webkit-linear-gradient(top, #555555, #555555); 512 | background-image: -o-linear-gradient(top, #555555, #555555); 513 | background-image: linear-gradient(top, #555555, #555555); 514 | background-repeat: repeat-x; 515 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#555555', GradientType=0); 516 | } 517 | .m-btn.black:hover, 518 | .m-btn.black:focus, 519 | .m-btn.black:active, 520 | .m-btn.black.active, 521 | .m-btn.black.disabled, 522 | .m-btn.black[disabled] { 523 | background-color: #222222; 524 | background-image: -moz-linear-gradient(top, #222222, #222222); 525 | background-image: -ms-linear-gradient(top, #222222, #222222); 526 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#222222)); 527 | background-image: -webkit-linear-gradient(top, #222222, #222222); 528 | background-image: -o-linear-gradient(top, #222222, #222222); 529 | background-image: linear-gradient(top, #222222, #222222); 530 | background-repeat: repeat-x; 531 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#222222', endColorstr='#222222', GradientType=0); 532 | } 533 | 534 | .m-btn.black:active, 535 | .m-btn.black.active 536 | { 537 | background-color: #222222; 538 | background-image: -moz-linear-gradient(top, #444444, #222222); 539 | background-image: -ms-linear-gradient(top, #444444, #222222); 540 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#222222)); 541 | background-image: -webkit-linear-gradient(top, #444444, #222222); 542 | background-image: -o-linear-gradient(top, #444444, #222222); 543 | background-image: linear-gradient(top, #444444, #222222); 544 | background-repeat: repeat-x; 545 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#444444', endColorstr='#222222', GradientType=0); 546 | 547 | } 548 | /* Mini-button */ 549 | .sm { 550 | font-size: 11px; 551 | } 552 | .mini 553 | { 554 | height: 13px; 555 | font-size: 11px; 556 | line-height: 13px; 557 | padding: 4px 10px; 558 | } 559 | .big 560 | { 561 | height: 38px; 562 | font-size: 18px; 563 | line-height: 38px; 564 | padding: 20px 26px; 565 | } 566 | 567 | .rnd 568 | { 569 | -webkit-border-radius: 5px; 570 | -moz-border-radius: 5px; 571 | border-radius: 5px; 572 | } 573 | 574 | .big.rnd 575 | { 576 | -webkit-border-radius: 11px; 577 | -moz-border-radius: 11px; 578 | border-radius: 11px; 579 | } 580 | 581 | /* Disabled */ 582 | .m-btn.disabled, .m-btn[disabled] { 583 | color: #999999; 584 | background-color: #f5f5f5; 585 | background-image: -moz-linear-gradient(top, #eeeeee, #dddddd); 586 | background-image: -ms-linear-gradient(top, #eeeeee, #dddddd); 587 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#eeeeee), to(#dddddd)); 588 | background-image: -webkit-linear-gradient(top, #eeeeee, #dddddd); 589 | background-image: -o-linear-gradient(top, #eeeeee, #dddddd); 590 | background-image: linear-gradient(top, #eeeeee, #dddddd); 591 | background-repeat: repeat-x; 592 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0); 593 | cursor: default; 594 | -webkit-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.25); 595 | -moz-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.25); 596 | box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.25); 597 | } 598 | /* Misc */ 599 | .m-btn.icn-only { 600 | min-width: 14px; 601 | } 602 | .m-btn.bigicn-only { 603 | min-width: 34px; 604 | } 605 | .m-btn-group { 606 | position: relative; 607 | display: inline-block; 608 | list-style: none; 609 | padding: 0; 610 | margin: 0; 611 | /* IE hacks */ 612 | 613 | zoom: 1; 614 | *display: inline; 615 | } 616 | .m-btn + .m-btn, 617 | .m-btn + .m-btn-group, 618 | .m-btn-group + .m-btn, 619 | .m-btn-group + .m-btn-group { 620 | margin-left: 15px; 621 | } 622 | 623 | .m-btn.dropdown-carettoggle { 624 | min-width: 5px; 625 | height: 18px; 626 | padding: 8px; 627 | } 628 | .m-btn.dropdown-carettoggle > .caret { 629 | margin-top: 8px; 630 | } 631 | .m-btn.caret:hover { 632 | opacity: 1; 633 | } 634 | 635 | .m-btn-group .m-btn { 636 | position: relative; 637 | float: left; 638 | margin-left: -1px; 639 | } 640 | 641 | .m-btn-group .m-btn:first-child { 642 | margin-left: 0; 643 | } 644 | 645 | .m-btn-group .m-btn.rnd:first-child { 646 | -webkit-border-radius: 5px 0 0 5px; 647 | -moz-border-radius: 5px 0 0 5px; 648 | border-radius: 5px 0 0 5px; 649 | } 650 | 651 | .m-btn-group .m-btn.rnd.dropdown-carettoggle { 652 | -webkit-border-radius: 0 5px 5px 0; 653 | -moz-border-radius: 0 5px 5px 0; 654 | border-radius: 0 5px 5px 0; 655 | } 656 | 657 | /* BUTTON CONTAINER */ 658 | /* For mixing buttons and button groups, e.g., in a navigation bar */ 659 | .m-btn-strip .m-btn, .m-btn-strip .m-btn-group { 660 | vertical-align: top; 661 | } 662 | .m-btn-group.open { 663 | *z-index: 1000; 664 | } 665 | 666 | .m-btn-group.open .dropdown-carettoggle, 667 | .m-btn-group.open .dropdown-toggle { 668 | background-image: none; 669 | -webkit-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.2); 670 | -moz-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.2); 671 | box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.2); 672 | } 673 | 674 | .m-btn-group.open .m-dropdown-menu { 675 | display: block; 676 | margin-top: 1px; 677 | } --------------------------------------------------------------------------------