├── lib ├── assets │ └── .keep ├── tasks │ └── .keep ├── templates │ └── haml │ │ └── scaffold │ │ └── _form.html.haml └── twitter_api.rb ├── public ├── favicon.ico ├── apple-touch-icon.png ├── apple-touch-icon-precomposed.png ├── robots.txt ├── humans.txt ├── 500.html ├── 422.html └── 404.html ├── app ├── assets │ ├── images │ │ ├── .keep │ │ ├── jumbotron.jpg │ │ ├── BitParrot_icon.png │ │ ├── favicon │ │ │ ├── favicon.ico │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── mstile-150x150.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── android-chrome-192x192.png │ │ │ ├── browserconfig.xml.erb │ │ │ ├── manifest.json.erb │ │ │ └── safari-pinned-tab.svg │ │ ├── BitParrot_logo_GrayFont.png │ │ └── Bonat_new_profile_pic_bw_colorburn100.jpg │ ├── javascripts │ │ ├── channels │ │ │ └── .keep │ │ ├── cable.js │ │ └── application.js │ ├── config │ │ └── manifest.js │ └── stylesheets │ │ ├── application.css.scss │ │ ├── modern-business.css │ │ └── 1st_load_framework.css.scss ├── models │ ├── concerns │ │ └── .keep │ ├── application_record.rb │ └── user.rb ├── controllers │ ├── concerns │ │ └── .keep │ ├── pages_controller.rb │ ├── visitors_controller.rb │ ├── application_controller.rb │ └── users_controller.rb ├── views │ ├── layouts │ │ ├── _navigation_links.html.haml │ │ ├── mailer.text.haml │ │ ├── _footer.html.haml │ │ ├── mailer.html.haml │ │ ├── _messages.html.haml │ │ ├── _nav_links_for_auth.html.haml │ │ ├── application.html.haml │ │ └── _navigation.html.haml │ ├── users │ │ ├── show.html.haml │ │ ├── index.html.haml │ │ └── _user.html.haml │ ├── shared │ │ └── _tweets.html.haml │ ├── devise │ │ ├── passwords │ │ │ ├── new.html.haml │ │ │ └── edit.html.haml │ │ ├── registrations │ │ │ ├── new.html.haml │ │ │ └── edit.html.haml │ │ └── sessions │ │ │ └── new.html.haml │ ├── pages │ │ ├── _resources.html.haml │ │ ├── _resources_python.html.haml │ │ ├── full-width.html.haml │ │ ├── _resources_machine_learning.html.haml │ │ ├── 404.html.haml │ │ ├── sidebar.html.haml │ │ ├── faq.html.haml │ │ ├── portfolio-item.html.haml │ │ ├── portfolio-4-col.html.haml │ │ ├── contact.html.haml │ │ ├── pricing.html.haml │ │ ├── portfolio-2-col.html.haml │ │ ├── blog-home-2.html.haml │ │ ├── about.html.haml │ │ ├── portfolio-1-col.html.haml │ │ ├── portfolio-3-col.html.haml │ │ ├── blog-home-1.html.haml │ │ ├── blog-post.html.haml │ │ └── services.html.haml │ ├── application │ │ └── _favicon.html.erb │ └── visitors │ │ ├── index.html.haml │ │ ├── python.html.haml │ │ ├── ruby_and_rails.html.haml │ │ └── machine_learning.html.haml ├── helpers │ ├── pages_helper.rb │ └── application_helper.rb ├── jobs │ └── application_job.rb ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── mailers │ └── application_mailer.rb ├── services │ └── create_admin_service.rb └── policies │ └── user_policy.rb ├── .ruby-gemset ├── .ruby-version ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── README ├── spec ├── support │ ├── pundit.rb │ ├── capybara.rb │ ├── factory_girl.rb │ ├── devise.rb │ ├── helpers.rb │ ├── database_cleaner.rb │ └── helpers │ │ └── session_helpers.rb ├── factories │ └── users.rb ├── models │ └── user_spec.rb ├── features │ ├── visitors │ │ ├── home_page_spec.rb │ │ ├── about_page_spec.rb │ │ ├── navigation_spec.rb │ │ └── sign_up_spec.rb │ └── users │ │ ├── sign_out_spec.rb │ │ ├── user_index_spec.rb │ │ ├── user_delete_spec.rb │ │ ├── user_show_spec.rb │ │ ├── user_edit_spec.rb │ │ └── sign_in_spec.rb ├── policies │ └── user_policy_spec.rb ├── rails_helper.rb └── spec_helper.rb ├── config ├── application.yml ├── spring.rb ├── boot.rb ├── environment.rb ├── cable.yml ├── initializers │ ├── session_store.rb │ ├── mime_types.rb │ ├── application_controller_renderer.rb │ ├── filter_parameter_logging.rb │ ├── cookies_serializer.rb │ ├── backtrace_silencers.rb │ ├── assets.rb │ ├── wrap_parameters.rb │ ├── pundit.rb │ ├── inflections.rb │ ├── new_framework_defaults.rb │ ├── simple_form_bootstrap.rb │ └── simple_form.rb ├── routes.rb ├── locales │ ├── en.yml │ ├── simple_form.en.yml │ ├── devise_invitable.en.yml │ └── devise.en.yml ├── application.rb ├── secrets.yml ├── favicon.json ├── database.yml ├── environments │ ├── test.rb │ ├── development.rb │ └── production.rb └── puma.rb ├── .rspec ├── bin ├── bundle ├── rspec ├── rake ├── rails ├── spring ├── update └── setup ├── config.ru ├── db ├── migrate │ ├── 20170322002223_add_name_to_users.rb │ ├── 20170322002235_add_role_to_users.rb │ ├── 20170322002226_add_confirmable_to_users.rb │ ├── 20170322002313_devise_invitable_add_to_users.rb │ └── 20170322002219_devise_create_users.rb ├── seeds.rb └── schema.rb ├── Rakefile ├── LICENSE ├── Gemfile ├── README.md ├── .gitignore └── Gemfile.lock /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | bitparrot 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.3.1 2 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Bit Parrot 2 | ================ 3 | 4 | -------------------------------------------------------------------------------- /app/views/layouts/_navigation_links.html.haml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.haml: -------------------------------------------------------------------------------- 1 | = yield 2 | -------------------------------------------------------------------------------- /spec/support/pundit.rb: -------------------------------------------------------------------------------- 1 | require 'pundit/rspec' 2 | -------------------------------------------------------------------------------- /app/helpers/pages_helper.rb: -------------------------------------------------------------------------------- 1 | module PagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/support/capybara.rb: -------------------------------------------------------------------------------- 1 | Capybara.asset_host = 'http://localhost:3000' 2 | -------------------------------------------------------------------------------- /config/application.yml: -------------------------------------------------------------------------------- 1 | # Add configuration values here, as shown below. 2 | 3 | 4 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | --require spec_helper 4 | --require rails_helper 5 | -------------------------------------------------------------------------------- /spec/support/factory_girl.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryGirl::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /app/assets/images/jumbotron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/jumbotron.jpg -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /spec/support/devise.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include Devise::TestHelpers, :type => :controller 3 | end 4 | -------------------------------------------------------------------------------- /app/assets/images/BitParrot_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/BitParrot_icon.png -------------------------------------------------------------------------------- /app/assets/images/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/favicon/favicon.ico -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /app/views/users/show.html.haml: -------------------------------------------------------------------------------- 1 | %h3 User 2 | %p 3 | Name: #{@user.name if @user.name} 4 | %p 5 | Email: #{@user.email if @user.email} 6 | -------------------------------------------------------------------------------- /app/assets/images/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /app/assets/images/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /app/assets/images/favicon/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/favicon/mstile-150x150.png -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/images/BitParrot_logo_GrayFont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/BitParrot_logo_GrayFont.png -------------------------------------------------------------------------------- /app/assets/images/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | %w( 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ).each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /app/assets/images/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /app/controllers/pages_controller.rb: -------------------------------------------------------------------------------- 1 | class PagesController < ApplicationController 2 | def show 3 | render template: "pages/#{params[:page]}" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/support/helpers.rb: -------------------------------------------------------------------------------- 1 | require 'support/helpers/session_helpers' 2 | RSpec.configure do |config| 3 | config.include Features::SessionHelpers, type: :feature 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/images/Bonat_new_profile_pic_bw_colorburn100.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michellebonat/bitparrot/HEAD/app/assets/images/Bonat_new_profile_pic_bw_colorburn100.jpg -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: async 6 | 7 | production: 8 | adapter: redis 9 | url: redis://localhost:6379/1 10 | -------------------------------------------------------------------------------- /app/views/shared/_tweets.html.haml: -------------------------------------------------------------------------------- 1 | -#%section#tweets 2 | -# %ul 3 | -# - @tweets.each do |tweet| 4 | -# %li= link_to tweet.text, "https://www.twitter.com/#{tweet.user.screen_name}" -------------------------------------------------------------------------------- /db/migrate/20170322002223_add_name_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddNameToUsers < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :users, :name, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170322002235_add_role_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddRoleToUsers < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :users, :role, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_bitparrot_session' 4 | -------------------------------------------------------------------------------- /app/views/layouts/_footer.html.haml: -------------------------------------------------------------------------------- 1 | / Footer 2 | .container 3 | %hr/ 4 | %footer 5 | .row 6 | .col-lg-12 7 | %p Copyright © Bit Parrot 2018 All Rights Reserved 8 | / /.container 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/views/users/index.html.haml: -------------------------------------------------------------------------------- 1 | .container 2 | .row 3 | %h3 Users 4 | .column 5 | %table.table 6 | %tbody 7 | - @users.each do |user| 8 | %tr 9 | = render user 10 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/ 5 | :css 6 | /* Email styles need to be inline */ 7 | %body 8 | = yield 9 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ApplicationController.renderer.defaults.merge!( 4 | # http_host: 'example.org', 5 | # https: false 6 | # ) 7 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.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 | -------------------------------------------------------------------------------- /bin/rspec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require 'bundler/setup' 8 | load Gem.bin_path('rspec-core', 'rspec') 9 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password, :password_confirmation] 5 | -------------------------------------------------------------------------------- /spec/factories/users.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :user do 3 | confirmed_at Time.now 4 | name "Test User" 5 | email "test@example.com" 6 | password "please123" 7 | 8 | trait :admin do 9 | role 'admin' 10 | end 11 | 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /spec/models/user_spec.rb: -------------------------------------------------------------------------------- 1 | describe User do 2 | 3 | before(:each) { @user = User.new(email: 'user@example.com') } 4 | 5 | subject { @user } 6 | 7 | it { should respond_to(:email) } 8 | 9 | it "#email returns a string" do 10 | expect(@user.email).to match 'user@example.com' 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /app/assets/images/favicon/browserconfig.xml.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #cba64b 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /lib/templates/haml/scaffold/_form.html.haml: -------------------------------------------------------------------------------- 1 | = simple_form_for(@<%= singular_table_name %>) do |f| 2 | = f.error_notification 3 | 4 | .form-inputs 5 | <%- attributes.each do |attribute| -%> 6 | = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> 7 | <%- end -%> 8 | 9 | .form-actions 10 | = f.button :submit 11 | -------------------------------------------------------------------------------- /db/migrate/20170322002226_add_confirmable_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddConfirmableToUsers < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :users, :confirmation_token, :string 4 | add_column :users, :confirmed_at, :datetime 5 | add_column :users, :confirmation_sent_at, :datetime 6 | add_column :users, :unconfirmed_email, :string 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/assets/images/favicon/manifest.json.erb: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bitparrot", 3 | "icons": [ 4 | { 5 | "src": "<%= asset_path 'favicon/android-chrome-192x192.png' %>", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | } 9 | ], 10 | "theme_color": "#cba64b", 11 | "background_color": "#cba64b", 12 | "display": "standalone" 13 | } -------------------------------------------------------------------------------- /app/views/users/_user.html.haml: -------------------------------------------------------------------------------- 1 | %td 2 | = link_to user.email, user 3 | %td 4 | = form_for(user) do |f| 5 | = f.select(:role, User.roles.keys.map {|role| [role.titleize,role]}) 6 | = f.submit 'Change Role', :class => 'button-xs' 7 | %td 8 | = link_to("Delete user", user_path(user), :data => { :confirm => "Are you sure?" }, :method => :delete, :class => 'button-xs') unless user == current_user 9 | -------------------------------------------------------------------------------- /app/views/layouts/_messages.html.haml: -------------------------------------------------------------------------------- 1 | -# Rails flash messages styled for Bootstrap 3.0 2 | - flash.each do |name, msg| 3 | - if msg.is_a?(String) 4 | %div{:class => "alert alert-dismissible alert-#{name.to_s == 'notice' ? 'success' : 'danger'}"} 5 | %button.close{"aria-hidden" => "true", "data-dismiss" => "alert", :type => "button"} × 6 | = content_tag :div, msg, :id => "flash_#{name}" 7 | -------------------------------------------------------------------------------- /app/services/create_admin_service.rb: -------------------------------------------------------------------------------- 1 | class CreateAdminService 2 | def call 3 | user = User.find_or_create_by!(email: Rails.application.secrets.admin_email) do |user| 4 | user.password = Rails.application.secrets.admin_password 5 | user.password_confirmation = Rails.application.secrets.admin_password 6 | user.confirm! 7 | user.admin! 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/controllers/visitors_controller.rb: -------------------------------------------------------------------------------- 1 | class VisitorsController < ApplicationController 2 | def index 3 | @meta_title = "Bit Parrot" 4 | end 5 | 6 | def ruby_and_rails 7 | @meta_title = "Ruby and Rails Developer Info" 8 | end 9 | 10 | def python 11 | @meta_title = "Python Developer Info" 12 | end 13 | 14 | def machine_learning 15 | @meta_title = "Machine Learning Developer Info" 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/layouts/_nav_links_for_auth.html.haml: -------------------------------------------------------------------------------- 1 | - if user_signed_in? 2 | %li= link_to 'Edit account', edit_user_registration_path 3 | %li= link_to 'Sign out', destroy_user_session_path, :method=>'delete' 4 | - else 5 | %li= link_to 'Sign in', new_user_session_path 6 | %li= link_to 'Sign up', new_user_registration_path 7 | - if user_signed_in? 8 | - if current_user.try(:admin?) 9 | %li= link_to 'Users', users_path 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the rails generate channel command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery with: :exception 3 | before_action :configure_permitted_parameters, if: :devise_controller? 4 | 5 | protected 6 | 7 | def configure_permitted_parameters 8 | devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) 9 | devise_parameter_sanitizer.permit(:account_update, keys: [:name]) 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /public/humans.txt: -------------------------------------------------------------------------------- 1 | /* the humans responsible & colophon */ 2 | /* humanstxt.org */ 3 | 4 | 5 | /* TEAM */ 6 | : 7 | Site: 8 | Twitter: 9 | Location: 10 | 11 | /* THANKS */ 12 | Daniel Kehoe (@rails_apps) for the RailsApps project 13 | 14 | /* SITE */ 15 | Standards: HTML5, CSS3 16 | Components: jQuery 17 | Software: Ruby on Rails 18 | 19 | /* GENERATED BY */ 20 | Rails Composer: http://railscomposer.com/ 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | user = CreateAdminService.new.call 9 | puts 'CREATED ADMIN USER: ' << user.email 10 | -------------------------------------------------------------------------------- /spec/features/visitors/home_page_spec.rb: -------------------------------------------------------------------------------- 1 | # Feature: Home page 2 | # As a visitor 3 | # I want to visit a home page 4 | # So I can learn more about the website 5 | feature 'Home page' do 6 | 7 | # Scenario: Visit the home page 8 | # Given I am a visitor 9 | # When I visit the home page 10 | # Then I see "Welcome" 11 | scenario 'visit the home page' do 12 | visit root_path 13 | expect(page).to have_content 'Welcome' 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /app/views/devise/passwords/new.html.haml: -------------------------------------------------------------------------------- 1 | .authform 2 | = form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post, :role => 'form'}) do |f| 3 | %h3 Forgot your password? 4 | %p We'll send password reset instructions. 5 | = devise_error_messages! 6 | .form-group 7 | = f.label :email 8 | = f.email_field :email, :autofocus => true, class: 'form-control' 9 | = f.submit 'Reset Password', :class => 'button right' 10 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ApplicationRecord 2 | enum role: [:user, :vip, :admin] 3 | after_initialize :set_default_role, :if => :new_record? 4 | 5 | def set_default_role 6 | self.role ||= :user 7 | end 8 | 9 | # Include default devise modules. Others available are: 10 | # :confirmable, :lockable, :timeoutable and :omniauthable 11 | devise :invitable, :database_authenticatable, :registerable, :confirmable, 12 | :recoverable, :rememberable, :trackable, :validatable 13 | end 14 | -------------------------------------------------------------------------------- /spec/features/visitors/about_page_spec.rb: -------------------------------------------------------------------------------- 1 | # Feature: 'About' page 2 | # As a visitor 3 | # I want to visit an 'about' page 4 | # So I can learn more about the website 5 | feature 'About page' do 6 | 7 | # Scenario: Visit the 'about' page 8 | # Given I am a visitor 9 | # When I visit the 'about' page 10 | # Then I see "About the Website" 11 | scenario 'Visit the about page' do 12 | visit 'pages/about' 13 | expect(page).to have_content 'About the Website' 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/database_cleaner.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.before(:suite) do 3 | DatabaseCleaner.clean_with(:truncation) 4 | end 5 | 6 | config.before(:each) do 7 | DatabaseCleaner.strategy = :transaction 8 | end 9 | 10 | config.before(:each, :js => true) do 11 | DatabaseCleaner.strategy = :truncation 12 | end 13 | 14 | config.before(:each) do 15 | DatabaseCleaner.start 16 | end 17 | 18 | config.append_after(:each) do 19 | DatabaseCleaner.clean 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/views/pages/_resources.html.haml: -------------------------------------------------------------------------------- 1 | .container 2 | .row 3 | .col-md-3 4 | %h1.page-header 5 | Resources 6 | -#%small Helpful Links 7 | .row 8 | .col-md-3 9 | .list-group 10 | = link_to 'Ruby Doc', "http://ruby-doc.org/", class: 'list-group-item', target: '_blank' 11 | = link_to 'Ruby on Rails Guides', "http://guides.rubyonrails.org/", class: 'list-group-item', target: '_blank' 12 | = link_to 'Ruby Gems', "https://rubygems.org/", class: 'list-group-item', target: '_blank' 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/policies/user_policy.rb: -------------------------------------------------------------------------------- 1 | class UserPolicy 2 | attr_reader :current_user, :model 3 | 4 | def initialize(current_user, model) 5 | @current_user = current_user 6 | @user = model 7 | end 8 | 9 | def index? 10 | @current_user.admin? 11 | end 12 | 13 | def show? 14 | @current_user.admin? or @current_user == @user 15 | end 16 | 17 | def update? 18 | @current_user.admin? 19 | end 20 | 21 | def destroy? 22 | return false if @current_user == @user 23 | @current_user.admin? 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /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 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require 'rubygems' 8 | require 'bundler' 9 | 10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) 11 | spring = lockfile.specs.detect { |spec| spec.name == "spring" } 12 | if spring 13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path 14 | gem 'spring', spring.version 15 | require 'spring/binstub' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root to: 'visitors#index' 3 | devise_for :users 4 | resources :users 5 | 6 | get "/pages/:page" => "pages#show" 7 | get 'pages/about', to: 'pages#about', as: :about 8 | get 'pages/faq', to: 'pages#faq', as: :faq 9 | get 'pages/contact', to: 'pages#contact', as: :contact 10 | get 'visitors/ruby_and_rails', to: 'visitors#ruby_and_rails', as: :ruby_and_rails 11 | get 'visitors/python', to: 'visitors#python', as: :python 12 | get 'visitors/machine_learning', to: 'visitors#machine_learning', as: :machine_learning 13 | end 14 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def parsed_tweet tweet 3 | _parsed_tweet = tweet.text.dup 4 | 5 | tweet.urls.each do |entity| 6 | html_link = link_to(entity.display_url.to_s, entity.expanded_url.to_s, target: '_blank') 7 | _parsed_tweet.sub!(entity.url.to_s, html_link) 8 | end 9 | 10 | tweet.media.each do |entity| 11 | html_link = link_to(entity.display_url.to_s, entity.expanded_url.to_s, target: '_blank') 12 | _parsed_tweet.sub!(entity.url.to_s, html_link) 13 | end 14 | 15 | _parsed_tweet.html_safe 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/helpers/session_helpers.rb: -------------------------------------------------------------------------------- 1 | module Features 2 | module SessionHelpers 3 | def sign_up_with(email, password, confirmation) 4 | visit new_user_registration_path 5 | fill_in 'Email', with: email 6 | fill_in 'Password', with: password 7 | fill_in 'Password confirmation', :with => confirmation 8 | click_button 'Sign up' 9 | end 10 | 11 | def signin(email, password) 12 | visit new_user_session_path 13 | fill_in 'Email', with: email 14 | fill_in 'Password', with: password 15 | click_button 'Sign in' 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/features/visitors/navigation_spec.rb: -------------------------------------------------------------------------------- 1 | # Feature: Navigation links 2 | # As a visitor 3 | # I want to see navigation links 4 | # So I can find home, sign in, or sign up 5 | feature 'Navigation links', :devise do 6 | 7 | # Scenario: View navigation links 8 | # Given I am a visitor 9 | # When I visit the home page 10 | # Then I see "home," "sign in," and "sign up" 11 | scenario 'view navigation links' do 12 | visit root_path 13 | expect(page).to have_content 'Home' 14 | expect(page).to have_content 'Sign in' 15 | expect(page).to have_content 'Sign up' 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /app/views/pages/_resources_python.html.haml: -------------------------------------------------------------------------------- 1 | .container 2 | .row 3 | .col-md-3 4 | %h1.page-header 5 | Python Resources 6 | -#%small Helpful Links 7 | .row 8 | .col-md-3 9 | .list-group 10 | = link_to 'Python Developer Guide', "https://www.python.org/dev/", class: 'list-group-item', target: '_blank' 11 | = link_to 'Best Python Resources', "https://www.fullstackpython.com/best-python-resources.html", class: 'list-group-item', target: '_blank' 12 | = link_to 'Python Packages List', "https://github.com/vinta/awesome-python", class: 'list-group-item', target: '_blank' 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/views/devise/passwords/edit.html.haml: -------------------------------------------------------------------------------- 1 | .authform 2 | = form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| 3 | %h3 Change your password 4 | = devise_error_messages! 5 | = f.hidden_field :reset_password_token 6 | .form-group 7 | = f.label :password, 'New password' 8 | = f.password_field :password, autofocus: true, autocomplete: 'off', class: 'form-control' 9 | = f.label :password_confirmation, 'Confirm new password' 10 | = f.password_field :password_confirmation, autocomplete: 'off', class: 'form-control' 11 | = f.submit 'Change my Password', :class => 'button right' 12 | -------------------------------------------------------------------------------- /spec/features/users/sign_out_spec.rb: -------------------------------------------------------------------------------- 1 | # Feature: Sign out 2 | # As a user 3 | # I want to sign out 4 | # So I can protect my account from unauthorized access 5 | feature 'Sign out', :devise do 6 | 7 | # Scenario: User signs out successfully 8 | # Given I am signed in 9 | # When I sign out 10 | # Then I see a signed out message 11 | scenario 'user signs out successfully' do 12 | user = FactoryGirl.create(:user) 13 | signin(user.email, user.password) 14 | expect(page).to have_content I18n.t 'devise.sessions.signed_in' 15 | click_link 'Sign out' 16 | expect(page).to have_content I18n.t 'devise.sessions.signed_out' 17 | end 18 | 19 | end 20 | 21 | 22 | -------------------------------------------------------------------------------- /config/initializers/pundit.rb: -------------------------------------------------------------------------------- 1 | # config/initializers/pundit.rb 2 | # Extends the ApplicationController to add Pundit for authorization. 3 | # Modify this file to change the behavior of a 'not authorized' error. 4 | # Be sure to restart your server when you modify this file. 5 | module PunditHelper 6 | extend ActiveSupport::Concern 7 | 8 | included do 9 | include Pundit 10 | rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized 11 | end 12 | 13 | private 14 | 15 | def user_not_authorized 16 | flash[:alert] = "Access denied." 17 | redirect_to (request.referrer || root_path) 18 | end 19 | 20 | end 21 | 22 | ApplicationController.send :include, PunditHelper 23 | -------------------------------------------------------------------------------- /spec/features/users/user_index_spec.rb: -------------------------------------------------------------------------------- 1 | include Warden::Test::Helpers 2 | Warden.test_mode! 3 | 4 | # Feature: User index page 5 | # As a user 6 | # I want to see a list of users 7 | # So I can see who has registered 8 | feature 'User index page', :devise do 9 | 10 | after(:each) do 11 | Warden.test_reset! 12 | end 13 | 14 | # Scenario: User listed on index page 15 | # Given I am signed in 16 | # When I visit the user index page 17 | # Then I see my own email address 18 | scenario 'user sees own email address' do 19 | user = FactoryGirl.create(:user, :admin) 20 | login_as(user, scope: :user) 21 | visit users_path 22 | expect(page).to have_content user.email 23 | end 24 | 25 | end 26 | -------------------------------------------------------------------------------- /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. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /app/views/devise/registrations/new.html.haml: -------------------------------------------------------------------------------- 1 | .authform 2 | = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :role => 'form'}) do |f| 3 | %h3 Sign Up 4 | = devise_error_messages! 5 | .form-group 6 | = f.label :name 7 | = f.text_field :name, class: 'form-control' 8 | .form-group 9 | = f.label :email 10 | = f.email_field :email, class: 'form-control' 11 | .form-group 12 | = f.label :password 13 | = f.password_field :password, class: 'form-control' 14 | .form-group 15 | = f.label :password_confirmation 16 | = f.password_field :password_confirmation, class: 'form-control' 17 | = f.submit 'Sign up', :class => 'button right' 18 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /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 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require bootstrap-sprockets 16 | //= require_tree . 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css.scss: -------------------------------------------------------------------------------- 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 bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /app/views/pages/full-width.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Full Width Page 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Full Width Page 13 | / /.row 14 | / Content Row 15 | .row 16 | .col-lg-12 17 | %p 18 | Most of Start Bootstrap's unstyled templates can be directly integrated into the Modern Business template. You can view all of our unstyled templates on our website at 19 | = succeed "." do 20 | %a{:href => "http://startbootstrap.com/template-categories/unstyled"} http://startbootstrap.com/template-categories/unstyled 21 | / /.row 22 | / /.container 23 | -------------------------------------------------------------------------------- /app/views/application/_favicon.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a way to update your development environment automatically. 15 | # Add necessary update steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | puts "\n== Updating database ==" 22 | system! 'bin/rails db:migrate' 23 | 24 | puts "\n== Removing old logs and tempfiles ==" 25 | system! 'bin/rails log:clear tmp:clear' 26 | 27 | puts "\n== Restarting application server ==" 28 | system! 'bin/rails restart' 29 | end 30 | -------------------------------------------------------------------------------- /spec/features/users/user_delete_spec.rb: -------------------------------------------------------------------------------- 1 | include Warden::Test::Helpers 2 | Warden.test_mode! 3 | 4 | # Feature: User delete 5 | # As a user 6 | # I want to delete my user profile 7 | # So I can close my account 8 | feature 'User delete', :devise, :js do 9 | 10 | after(:each) do 11 | Warden.test_reset! 12 | end 13 | 14 | # Scenario: User can delete own account 15 | # Given I am signed in 16 | # When I delete my account 17 | # Then I should see an account deleted message 18 | scenario 'user can delete own account' do 19 | skip 'skip a slow test' 20 | user = FactoryGirl.create(:user) 21 | login_as(user, :scope => :user) 22 | visit edit_user_registration_path(user) 23 | click_button 'Cancel my account' 24 | page.driver.browser.switch_to.alert.accept 25 | expect(page).to have_content I18n.t 'devise.registrations.destroyed' 26 | end 27 | 28 | end 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | class UsersController < ApplicationController 2 | before_action :authenticate_user! 3 | after_action :verify_authorized 4 | 5 | def index 6 | @users = User.all 7 | authorize User 8 | end 9 | 10 | def show 11 | @user = User.find(params[:id]) 12 | authorize @user 13 | end 14 | 15 | def update 16 | @user = User.find(params[:id]) 17 | authorize @user 18 | if @user.update_attributes(secure_params) 19 | redirect_to users_path, :notice => "User updated." 20 | else 21 | redirect_to users_path, :alert => "Unable to update user." 22 | end 23 | end 24 | 25 | def destroy 26 | user = User.find(params[:id]) 27 | authorize user 28 | user.destroy 29 | redirect_to users_path, :notice => "User deleted." 30 | end 31 | 32 | private 33 | 34 | def secure_params 35 | params.require(:user).permit(:role) 36 | end 37 | 38 | end 39 | -------------------------------------------------------------------------------- /app/views/devise/sessions/new.html.haml: -------------------------------------------------------------------------------- 1 | .authform 2 | = form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :role => 'form'}) do |f| 3 | %h3 Sign In 4 | = devise_error_messages! 5 | .form-group 6 | - if devise_mapping.registerable? 7 | = link_to 'Sign up', new_registration_path(resource_name), class: 'right' 8 | = f.label :email 9 | = f.email_field :email, :autofocus => true, class: 'form-control' 10 | .form-group 11 | - if devise_mapping.recoverable? 12 | = link_to "Forgot password?", new_password_path(resource_name), class: 'right' 13 | = f.label :password 14 | = f.password_field :password, class: 'form-control' 15 | = f.submit 'Sign in', :class => 'button right' 16 | - if devise_mapping.rememberable? 17 | .checkbox{:style => "width:150px"} 18 | %label 19 | = f.check_box :remember_me 20 | Remember me 21 | -------------------------------------------------------------------------------- /db/migrate/20170322002313_devise_invitable_add_to_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseInvitableAddToUsers < ActiveRecord::Migration 2 | def up 3 | change_table :users do |t| 4 | t.string :invitation_token 5 | t.datetime :invitation_created_at 6 | t.datetime :invitation_sent_at 7 | t.datetime :invitation_accepted_at 8 | t.integer :invitation_limit 9 | t.references :invited_by, polymorphic: true 10 | t.integer :invitations_count, default: 0 11 | t.index :invitations_count 12 | t.index :invitation_token, unique: true # for invitable 13 | t.index :invited_by_id 14 | end 15 | end 16 | 17 | def down 18 | change_table :users do |t| 19 | t.remove_references :invited_by, polymorphic: true 20 | t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ 5 | %meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"}/ 6 | %title= @meta_title 7 | %meta{:content => "#{content_for?(:description) ? yield(:description) : "My Application"}", :name => "description"}/ 8 | = render 'application/favicon' 9 | = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true 10 | = javascript_include_tag 'application', 'data-turbolinks-track' => true 11 | = csrf_meta_tags 12 | / Custom Fonts 13 | %link{:href => "https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css", :rel => "stylesheet"}/ 14 | %body 15 | %header 16 | = render 'layouts/navigation' 17 | = render 'layouts/messages' 18 | = yield 19 | = render 'shared/tweets' 20 | = render 'layouts/footer' 21 | -------------------------------------------------------------------------------- /app/views/visitors/index.html.haml: -------------------------------------------------------------------------------- 1 | %body 2 | %header#myCarousel.carousel.slide 3 | .carousel-inner 4 | .item.active 5 | .fill 6 | = link_to image_tag('jumbotron.jpg') 7 | .carousel-caption 8 | %h1 So developers can track info they need 9 | %br 10 | = link_to 'Ruby Rails Info Stream', ruby_and_rails_path, class: 'btn btn-round btn-lg btn-primary' 11 | = link_to 'Python Info Stream', python_path, class: 'btn btn-round btn-lg btn-primary' 12 | = link_to 'ML Info Stream', machine_learning_path, class: 'btn btn-round btn-lg btn-primary' 13 | 14 | .container 15 | .row 16 | .col-lg-12 17 | %h3 18 | %br 19 | %p Want Bit Parrot to track other info for you? 20 | %p Tweet Us 21 | %ul.list-inline 22 | %li 23 | %a{:href => "https://twitter.com/bit_parrot"} 24 | %i.fa.fa-2x.fa-twitter-square 25 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Bitparrot 10 | class Application < Rails::Application 11 | config.eager_load_paths << Rails.root.join('lib') 12 | 13 | config.generators do |g| 14 | g.test_framework :rspec, 15 | fixtures: true, 16 | view_specs: false, 17 | helper_specs: false, 18 | routing_specs: false, 19 | controller_specs: false, 20 | request_specs: false 21 | g.fixture_replacement :factory_girl, dir: "spec/factories" 22 | end 23 | 24 | # Settings in config/environments/* take precedence over those specified here. 25 | # Application configuration should go into files in config/initializers 26 | # -- all .rb files in that directory are automatically loaded. 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /config/locales/simple_form.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | simple_form: 3 | "yes": 'Yes' 4 | "no": 'No' 5 | required: 6 | text: 'required' 7 | mark: '*' 8 | # You can uncomment the line below if you need to overwrite the whole required html. 9 | # When using html, text and mark won't be used. 10 | # html: '*' 11 | error_notification: 12 | default_message: "Please review the problems below:" 13 | # Examples 14 | # labels: 15 | # defaults: 16 | # password: 'Password' 17 | # user: 18 | # new: 19 | # email: 'E-mail to sign in.' 20 | # edit: 21 | # email: 'E-mail.' 22 | # hints: 23 | # defaults: 24 | # username: 'User name to sign in.' 25 | # password: 'No special characters, please.' 26 | # include_blanks: 27 | # defaults: 28 | # age: 'Rather not say' 29 | # prompts: 30 | # defaults: 31 | # age: 'Select your age' 32 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a starting point to setup your application. 15 | # Add necessary setup steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | # puts "\n== Copying sample files ==" 22 | # unless File.exist?('config/database.yml') 23 | # cp 'config/database.yml.sample', 'config/database.yml' 24 | # end 25 | 26 | puts "\n== Preparing database ==" 27 | system! 'bin/rails db:setup' 28 | 29 | puts "\n== Removing old logs and tempfiles ==" 30 | system! 'bin/rails log:clear tmp:clear' 31 | 32 | puts "\n== Restarting application server ==" 33 | system! 'bin/rails restart' 34 | end 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Michelle Bonat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config/initializers/new_framework_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains migration options to ease your Rails 5.0 upgrade. 4 | # 5 | # Read the Guide for Upgrading Ruby on Rails for more info on each option. 6 | 7 | # Enable per-form CSRF tokens. Previous versions had false. 8 | Rails.application.config.action_controller.per_form_csrf_tokens = true 9 | 10 | # Enable origin-checking CSRF mitigation. Previous versions had false. 11 | Rails.application.config.action_controller.forgery_protection_origin_check = true 12 | 13 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. 14 | # Previous versions had false. 15 | ActiveSupport.to_time_preserves_timezone = true 16 | 17 | # Require `belongs_to` associations by default. Previous versions had false. 18 | Rails.application.config.active_record.belongs_to_required_by_default = true 19 | 20 | # Do not halt callback chains when a callback returns false. Previous versions had true. 21 | ActiveSupport.halt_callback_chains_on_return_false = false 22 | 23 | # Configure SSL options to enable HSTS with subdomains. Previous versions had false. 24 | Rails.application.config.ssl_options = { hsts: { subdomains: true } } 25 | -------------------------------------------------------------------------------- /app/views/layouts/_navigation.html.haml: -------------------------------------------------------------------------------- 1 | %nav.navbar.navbar-default.navbar-fixed-top 2 | .container 3 | .navbar-header 4 | %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", :type => "button"} 5 | %span.sr-only Toggle navigation 6 | %span.icon-bar 7 | %span.icon-bar 8 | %span.icon-bar 9 | = link_to image_tag('BitParrot_logo_GrayFont.png', width: 150, height: 50, align: 'left', style: 'margin: 0px 0px 10px 0px'), root_path 10 | = link_to 'Home', root_path, class: 'navbar-brand', style: 'margin: 0px 0px 0px 15px' 11 | = link_to 'Ruby | Rails', ruby_and_rails_path, class: 'navbar-brand', style: 'margin: 0px 0px 0px 0px' 12 | = link_to 'Python', python_path, class: 'navbar-brand', style: 'margin: 0px 0px 0px 0px' 13 | = link_to 'Machine Learning', machine_learning_path, class: 'navbar-brand', style: 'margin: 0px 0px 0px 0px' 14 | = link_to 'About', about_path, class: 'navbar-brand', style: 'margin: 0px 15px 0px 0px' 15 | = link_to 'FAQ', faq_path, class: 'navbar-brand' 16 | -#= link_to 'Sign In', new_user_session_path, class: 'navbar-brand' 17 | -#= link_to 'Sign Up', new_user_registration_path, class: 'navbar-brand' 18 | .collapse.navbar-collapse 19 | %ul.nav.navbar-nav 20 | = render 'layouts/navigation_links' -------------------------------------------------------------------------------- /spec/features/users/user_show_spec.rb: -------------------------------------------------------------------------------- 1 | include Warden::Test::Helpers 2 | Warden.test_mode! 3 | 4 | # Feature: User profile page 5 | # As a user 6 | # I want to visit my user profile page 7 | # So I can see my personal account data 8 | feature 'User profile page', :devise do 9 | 10 | after(:each) do 11 | Warden.test_reset! 12 | end 13 | 14 | # Scenario: User sees own profile 15 | # Given I am signed in 16 | # When I visit the user profile page 17 | # Then I see my own email address 18 | scenario 'user sees own profile' do 19 | user = FactoryGirl.create(:user) 20 | login_as(user, :scope => :user) 21 | visit user_path(user) 22 | expect(page).to have_content 'User' 23 | expect(page).to have_content user.email 24 | end 25 | 26 | # Scenario: User cannot see another user's profile 27 | # Given I am signed in 28 | # When I visit another user's profile 29 | # Then I see an 'access denied' message 30 | scenario "user cannot see another user's profile" do 31 | me = FactoryGirl.create(:user) 32 | other = FactoryGirl.create(:user, email: 'other@example.com') 33 | login_as(me, :scope => :user) 34 | Capybara.current_session.driver.header 'Referer', root_path 35 | visit user_path(other) 36 | expect(page).to have_content 'Access denied.' 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /app/views/visitors/python.html.haml: -------------------------------------------------------------------------------- 1 | %body 2 | .container 3 | .row 4 | .col-md-9 5 | %h1.page-header 6 | Python Info Stream 7 | %p 8 | = link_to 'Refresh Data', python_path, class: 'btn btn-round btn-primary', style: 'margin: 0 0 10px', :method => :get 9 | %h2 10 | Updates from the official Python Software Foundation 11 | %h4 12 | Tweets from @ThePSF aka Python Software 13 | %ul 14 | - TwitterApi.thepsf_tweets.each do |tweet| 15 | %li= parsed_tweet tweet 16 | 17 | %h2 18 | Podcasts 19 | %h4 20 | Tweets from @TalkPython aka Talk Python Podcasts 21 | %ul 22 | - TwitterApi.talkpython_tweets.each do |tweet| 23 | %li= parsed_tweet tweet 24 | 25 | %h2 26 | Jobs 27 | %h4 28 | Tweets from @pyjobo aka Python Jobs Board 29 | %ul 30 | - TwitterApi.pyjobo_tweets.each do |tweet| 31 | %li= parsed_tweet tweet 32 | .row 33 | .col-md-3 34 | .well 35 | = render partial: 'pages/resources_python' 36 | 37 | :javascript 38 | $(document).on('ready', function () { 39 | $('.carousel').carousel({ 40 | interval: 1000 //changes the speed 41 | }) 42 | }); 43 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | git_source(:github) do |repo_name| 3 | repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") 4 | "https://github.com/#{repo_name}.git" 5 | end 6 | ruby '2.3.1' 7 | gem 'rails', '~> 5.0.2' 8 | gem 'puma', '~> 3.0' 9 | gem 'sass-rails', '~> 5.0' 10 | gem 'uglifier', '>= 1.3.0' 11 | gem 'coffee-rails', '~> 4.2' 12 | gem 'jquery-rails' 13 | gem 'turbolinks', '~> 5' 14 | gem 'jbuilder', '~> 2.5' 15 | gem 'figaro' 16 | gem 'twitter' 17 | gem 'httparty' 18 | 19 | group :development, :test do 20 | gem 'byebug', platform: :mri 21 | end 22 | group :development do 23 | gem 'web-console', '>= 3.3.0' 24 | gem 'listen', '~> 3.0.5' 25 | gem 'spring' 26 | gem 'spring-watcher-listen', '~> 2.0.0' 27 | gem 'rails_real_favicon' 28 | gem 'letter_opener' 29 | end 30 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 31 | gem 'bootstrap-sass' 32 | gem 'devise' 33 | gem 'devise_invitable' 34 | gem 'haml-rails' 35 | gem 'high_voltage' 36 | gem 'pg' 37 | gem 'pundit' 38 | gem 'simple_form' 39 | group :development do 40 | gem 'better_errors' 41 | gem 'html2haml' 42 | gem 'rails_layout' 43 | gem 'spring-commands-rspec' 44 | end 45 | group :development, :test do 46 | gem 'factory_girl_rails' 47 | gem 'faker' 48 | gem 'rspec-rails' 49 | end 50 | group :test do 51 | gem 'capybara' 52 | gem 'database_cleaner' 53 | gem 'launchy' 54 | gem 'selenium-webdriver' 55 | end 56 | -------------------------------------------------------------------------------- /config/locales/devise_invitable.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | devise: 3 | failure: 4 | invited: "You have a pending invitation, accept it to finish creating your account." 5 | invitations: 6 | send_instructions: "An invitation email has been sent to %{email}." 7 | invitation_token_invalid: "The invitation token provided is not valid!" 8 | updated: "Your password was set successfully. You are now signed in." 9 | updated_not_active: "Your password was set successfully." 10 | no_invitations_remaining: "No invitations remaining" 11 | invitation_removed: "Your invitation was removed." 12 | new: 13 | header: "Send invitation" 14 | submit_button: "Send an invitation" 15 | edit: 16 | header: "Set your password" 17 | submit_button: "Set my password" 18 | mailer: 19 | invitation_instructions: 20 | subject: "Invitation instructions" 21 | hello: "Hello %{email}" 22 | someone_invited_you: "Someone has invited you to %{url}, you can accept it through the link below." 23 | accept: "Accept invitation" 24 | accept_until: "This invitation will be due in %{due_date}." 25 | ignore: "If you don't want to accept the invitation, please ignore this email.
\nYour account won't be created until you access the link above and set your password." 26 | time: 27 | formats: 28 | devise: 29 | mailer: 30 | invitation_instructions: 31 | accept_until_format: "%B %d, %Y %I:%M %p" 32 | -------------------------------------------------------------------------------- /spec/policies/user_policy_spec.rb: -------------------------------------------------------------------------------- 1 | describe UserPolicy do 2 | subject { UserPolicy } 3 | 4 | let (:current_user) { FactoryGirl.build_stubbed :user } 5 | let (:other_user) { FactoryGirl.build_stubbed :user } 6 | let (:admin) { FactoryGirl.build_stubbed :user, :admin } 7 | 8 | permissions :index? do 9 | it "denies access if not an admin" do 10 | expect(UserPolicy).not_to permit(current_user) 11 | end 12 | it "allows access for an admin" do 13 | expect(UserPolicy).to permit(admin) 14 | end 15 | end 16 | 17 | permissions :show? do 18 | it "prevents other users from seeing your profile" do 19 | expect(subject).not_to permit(current_user, other_user) 20 | end 21 | it "allows you to see your own profile" do 22 | expect(subject).to permit(current_user, current_user) 23 | end 24 | it "allows an admin to see any profile" do 25 | expect(subject).to permit(admin) 26 | end 27 | end 28 | 29 | permissions :update? do 30 | it "prevents updates if not an admin" do 31 | expect(subject).not_to permit(current_user) 32 | end 33 | it "allows an admin to make updates" do 34 | expect(subject).to permit(admin) 35 | end 36 | end 37 | 38 | permissions :destroy? do 39 | it "prevents deleting yourself" do 40 | expect(subject).not_to permit(current_user, current_user) 41 | end 42 | it "allows an admin to delete any user" do 43 | expect(subject).to permit(admin, other_user) 44 | end 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /app/views/visitors/ruby_and_rails.html.haml: -------------------------------------------------------------------------------- 1 | %body 2 | .container 3 | .row 4 | .col-md-9 5 | %h1.page-header 6 | Ruby And Rails Info Stream 7 | %p 8 | = link_to 'Refresh Data', root_path, class: 'btn btn-round btn-primary', style: 'margin: 0 0 10px', :method => :get 9 | -#%h2 10 | -# Ruby On Rails News 11 | -# %h4 12 | -# Tweets from @RubyonRailsNews 13 | -#%ul 14 | -# - TwitterApi.rornews_tweets.each do |tweet| 15 | -# %li= parsed_tweet tweet 16 | %h2 17 | Ruby Inside (content from weekly newsletter) 18 | %h4 19 | Tweets from @RubyInside 20 | %ul 21 | - TwitterApi.rubyinside_tweets.each do |tweet| 22 | %li= parsed_tweet tweet 23 | -#%h2 24 | -# Ruby On Rails Content 25 | -# %h4 26 | -# Tweets from @RubyonRRails 27 | -#%ul 28 | -# - TwitterApi.railscontent_tweets.each do |tweet| 29 | -# %li= parsed_tweet tweet 30 | %h2 31 | Ruby On Rails Jobs 32 | %h4 33 | Tweets from @rorjobs 34 | %ul 35 | - TwitterApi.rorjobs_tweets.each do |tweet| 36 | %li= parsed_tweet tweet 37 | .row 38 | .col-md-3 39 | .well 40 | = render partial: 'pages/resources' 41 | 42 | :javascript 43 | $(document).on('ready', function () { 44 | $('.carousel').carousel({ 45 | interval: 1000 //changes the speed 46 | }) 47 | }); 48 | -------------------------------------------------------------------------------- /app/views/visitors/machine_learning.html.haml: -------------------------------------------------------------------------------- 1 | %body 2 | .container 3 | .row 4 | .col-md-9 5 | %h1.page-header 6 | Machine Learning Info Stream 7 | %p 8 | = link_to 'Refresh Data', machine_learning_path, class: 'btn btn-round btn-primary', style: 'margin: 0 0 10px', :method => :get 9 | -#%h2 10 | -# Updates about #ml #machinelearning #nlp #aicontent curated by top Machine Learning, NLP, AI Influencers via @rightrelevance. Moderated by @vmishrra 11 | -# %h4 12 | -# Tweets from @ML_toparticles 13 | -#%ul 14 | -# - TwitterApi.ml_toparticles_tweets.each do |tweet| 15 | -# %li= parsed_tweet tweet 16 | 17 | %h2 18 | Official Twitter feed for Machine Learning thread on Reddit 19 | %h4 20 | Tweets from @slashML 21 | %ul 22 | - TwitterApi.talkpython_tweets.each do |tweet| 23 | %li= parsed_tweet tweet 24 | 25 | %h2 26 | Jobs Boards listing by #ODSC: Data Science, Machine Learning, AI, Deep Learning 27 | %h4 28 | Tweets from @CareersAI 29 | %ul 30 | - TwitterApi.talkpython_tweets.each do |tweet| 31 | %li= parsed_tweet tweet 32 | 33 | .row 34 | .col-md-3 35 | .well 36 | = render partial: 'pages/resources_machine_learning' 37 | 38 | :javascript 39 | $(document).on('ready', function () { 40 | $('.carousel').carousel({ 41 | interval: 1000 //changes the speed 42 | }) 43 | }); 44 | -------------------------------------------------------------------------------- /db/migrate/20170322002219_devise_create_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateUsers < ActiveRecord::Migration[5.0] 2 | def change 3 | create_table :users do |t| 4 | ## Database authenticatable 5 | t.string :email, null: false, default: "" 6 | t.string :encrypted_password, null: false, default: "" 7 | 8 | ## Recoverable 9 | t.string :reset_password_token 10 | t.datetime :reset_password_sent_at 11 | 12 | ## Rememberable 13 | t.datetime :remember_created_at 14 | 15 | ## Trackable 16 | t.integer :sign_in_count, default: 0, null: false 17 | t.datetime :current_sign_in_at 18 | t.datetime :last_sign_in_at 19 | t.inet :current_sign_in_ip 20 | t.inet :last_sign_in_ip 21 | 22 | ## Confirmable 23 | # t.string :confirmation_token 24 | # t.datetime :confirmed_at 25 | # t.datetime :confirmation_sent_at 26 | # t.string :unconfirmed_email # Only if using reconfirmable 27 | 28 | ## Lockable 29 | # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts 30 | # t.string :unlock_token # Only if unlock strategy is :email or :both 31 | # t.datetime :locked_at 32 | 33 | 34 | t.timestamps null: false 35 | end 36 | 37 | add_index :users, :email, unique: true 38 | add_index :users, :reset_password_token, unique: true 39 | # add_index :users, :confirmation_token, unique: true 40 | # add_index :users, :unlock_token, unique: true 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /app/views/devise/registrations/edit.html.haml: -------------------------------------------------------------------------------- 1 | .authform 2 | %h3 3 | Edit #{resource_name.to_s.humanize} 4 | = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :role => 'form'}) do |f| 5 | = devise_error_messages! 6 | .form-group 7 | = f.label :name 8 | = f.text_field :name, :autofocus => true, class: 'form-control' 9 | .form-group 10 | = f.label :email 11 | = f.email_field :email, class: 'form-control' 12 | - if devise_mapping.confirmable? && resource.pending_reconfirmation? 13 | %div 14 | Currently waiting confirmation for: #{resource.unconfirmed_email} 15 | %fieldset 16 | %p Leave these fields blank if you don't want to change your password. 17 | .form-group 18 | = f.label :password 19 | = f.password_field :password, :autocomplete => 'off', class: 'form-control' 20 | .form-group 21 | = f.label :password_confirmation 22 | = f.password_field :password_confirmation, class: 'form-control' 23 | %fieldset 24 | %p You must enter your current password to make changes. 25 | .form-group 26 | = f.label :current_password 27 | = f.password_field :current_password, class: 'form-control' 28 | = f.submit 'Update', :class => 'button right' 29 | .authform 30 | %h3 Cancel Account 31 | %p Unhappy? We'll be sad to see you go. 32 | = button_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete, :class => 'button right' 33 | -------------------------------------------------------------------------------- /spec/features/users/user_edit_spec.rb: -------------------------------------------------------------------------------- 1 | include Warden::Test::Helpers 2 | Warden.test_mode! 3 | 4 | # Feature: User edit 5 | # As a user 6 | # I want to edit my user profile 7 | # So I can change my email address 8 | feature 'User edit', :devise do 9 | 10 | after(:each) do 11 | Warden.test_reset! 12 | end 13 | 14 | # Scenario: User changes email address 15 | # Given I am signed in 16 | # When I change my email address 17 | # Then I see an account updated message 18 | scenario 'user changes email address' do 19 | user = FactoryGirl.create(:user) 20 | login_as(user, :scope => :user) 21 | visit edit_user_registration_path(user) 22 | fill_in 'Email', :with => 'newemail@example.com' 23 | fill_in 'Current password', :with => user.password 24 | click_button 'Update' 25 | txts = [I18n.t( 'devise.registrations.updated'), I18n.t( 'devise.registrations.update_needs_confirmation')] 26 | expect(page).to have_content(/.*#{txts[0]}.*|.*#{txts[1]}.*/) 27 | end 28 | 29 | # Scenario: User cannot edit another user's profile 30 | # Given I am signed in 31 | # When I try to edit another user's profile 32 | # Then I see my own 'edit profile' page 33 | scenario "user cannot cannot edit another user's profile", :me do 34 | me = FactoryGirl.create(:user) 35 | other = FactoryGirl.create(:user, email: 'other@example.com') 36 | login_as(me, :scope => :user) 37 | visit edit_user_registration_path(other) 38 | expect(page).to have_content 'Edit User' 39 | expect(page).to have_field('Email', with: me.email) 40 | end 41 | 42 | end 43 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | admin_name: First User 15 | admin_email: user@example.com 16 | admin_password: changeme 17 | email_provider_username: <%= ENV["SENDGRID_USERNAME"] %> 18 | email_provider_password: <%= ENV["SENDGRID_PASSWORD"] %> 19 | domain_name: bitparrot.co 20 | secret_key_base: adb0be64c096c68b799ee52ec7190d9ee51e6df9f057e23cee9f96cd56a033999bd8ede511f50d37cba28b69a08ae1bbeebeaf3ffdc977c043781e2bab9ff8d1 21 | 22 | test: 23 | export DOMAIN_NAME="bitparrot.co" 24 | # commenting this as it is showing as creating an error 25 | # secret_key_base: 03f14ebf058a8bab549ad92c64df21b74de692bc522ac77075ceb39f6cc343920b1c9bd88cccefdf2f7c17ae91786c61bdb93e7a1d855134488561ca93ce7282 26 | 27 | # Do not keep production secrets in the repository, 28 | # instead read values from the environment. 29 | production: 30 | admin_name: <%= ENV["ADMIN_NAME"] %> 31 | admin_email: <%= ENV["ADMIN_EMAIL"] %> 32 | admin_password: <%= ENV["ADMIN_PASSWORD"] %> 33 | email_provider_username: <%= ENV["SENDGRID_USERNAME"] %> 34 | email_provider_password: <%= ENV["SENDGRID_PASSWORD"] %> 35 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 36 | -------------------------------------------------------------------------------- /config/favicon.json: -------------------------------------------------------------------------------- 1 | { 2 | "master_picture": "app/assets/images/BitParrot_icon.png", 3 | "favicon_design": { 4 | "ios": { 5 | "picture_aspect": "background_and_margin", 6 | "background_color": "#cba64b", 7 | "margin": "14%", 8 | "assets": { 9 | "ios6_and_prior_icons": false, 10 | "ios7_and_later_icons": false, 11 | "precomposed_icons": false, 12 | "declare_only_default_icon": true 13 | }, 14 | "app_name": "bitparrot" 15 | }, 16 | "desktop_browser": [ 17 | 18 | ], 19 | "windows": { 20 | "picture_aspect": "no_change", 21 | "background_color": "#cba64b", 22 | "on_conflict": "override", 23 | "assets": { 24 | "windows_80_ie_10_tile": false, 25 | "windows_10_ie_11_edge_tiles": { 26 | "small": false, 27 | "medium": true, 28 | "big": false, 29 | "rectangle": false 30 | } 31 | }, 32 | "app_name": "bitparrot" 33 | }, 34 | "android_chrome": { 35 | "picture_aspect": "no_change", 36 | "theme_color": "#cba64b", 37 | "manifest": { 38 | "name": "bitparrot", 39 | "display": "standalone", 40 | "orientation": "not_set", 41 | "on_conflict": "override", 42 | "declared": true 43 | }, 44 | "assets": { 45 | "legacy_icon": false, 46 | "low_resolution_icons": false 47 | } 48 | }, 49 | "safari_pinned_tab": { 50 | "picture_aspect": "silhouette", 51 | "theme_color": "#cba64b" 52 | } 53 | }, 54 | "settings": { 55 | "scaling_algorithm": "Mitchell", 56 | "error_on_image_too_small": false 57 | } 58 | } -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /lib/twitter_api.rb: -------------------------------------------------------------------------------- 1 | class TwitterApi 2 | def self.rornews_tweets 3 | client.user_timeline('rubyonrailsnews', count: 10, exclude_replies: true, include_rts: false) 4 | end 5 | 6 | def self.railscontent_tweets 7 | client.user_timeline('rubyonrrails', count: 10, exclude_replies: true, include_rts: false) 8 | end 9 | 10 | def self.rorjobs_tweets 11 | client.user_timeline('rorjobs', count: 20, exclude_replies: true, include_rts: false) 12 | end 13 | 14 | def self.rubyinside_tweets 15 | client.user_timeline('rubyinside', count: 20, exclude_replies: true, include_rts: false) 16 | end 17 | 18 | def self.thepsf_tweets 19 | client.user_timeline('thepsf', count: 20, exclude_replies: true, include_rts: false) 20 | end 21 | 22 | def self.talkpython_tweets 23 | client.user_timeline('talkpython', count: 20, exclude_replies: true, include_rts: false) 24 | end 25 | 26 | def self.pyjobo_tweets 27 | client.user_timeline('pyjobo', count: 20, exclude_replies: true, include_rts: false) 28 | end 29 | 30 | def self.ml_toparticles_tweets 31 | client.user_timeline('ml_toparticles', count: 20, exclude_replies: true, include_rts: false) 32 | end 33 | 34 | def self.slashml_tweets 35 | client.user_timeline('slashml', count: 20, exclude_replies: true, include_rts: false) 36 | end 37 | 38 | def self.careersai_tweets 39 | client.user_timeline('careersai', count: 20, exclude_replies: true, include_rts: false) 40 | end 41 | 42 | def self.client 43 | @client ||= Twitter::REST::Client.new do |config| 44 | config.consumer_key = ENV['TWITTER_CONSUMER_KEY'] 45 | config.consumer_secret = ENV['TWITTER_CONSUMER_SECRET'] 46 | end 47 | end 48 | end 49 | 50 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

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

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /app/assets/stylesheets/modern-business.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - Modern Business HTML Template (http://startbootstrap.com) 3 | * Code licensed under the Apache License v2.0. 4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0. 5 | */ 6 | 7 | /* Global Styles */ 8 | 9 | html, 10 | body { 11 | height: 100%; 12 | } 13 | 14 | body { 15 | padding-top: 50px; /* Required padding for .navbar-fixed-top. Remove if using .navbar-static-top. Change if height of navigation changes. */ 16 | } 17 | 18 | .img-portfolio { 19 | margin-bottom: 30px; 20 | } 21 | 22 | .img-hover:hover { 23 | opacity: 0.8; 24 | } 25 | 26 | /* Home Page Carousel */ 27 | 28 | header.carousel { 29 | height: 50%; 30 | } 31 | 32 | header.carousel .item, 33 | header.carousel .item.active, 34 | header.carousel .carousel-inner { 35 | height: 100%; 36 | } 37 | 38 | header.carousel .fill { 39 | width: 100%; 40 | height: 100%; 41 | background-position: center; 42 | background-size: cover; 43 | } 44 | 45 | /* 404 Page Styles */ 46 | 47 | .error-404 { 48 | font-size: 100px; 49 | } 50 | 51 | /* Pricing Page Styles */ 52 | 53 | .price { 54 | display: block; 55 | font-size: 50px; 56 | line-height: 50px; 57 | } 58 | 59 | .price sup { 60 | top: -20px; 61 | left: 2px; 62 | font-size: 20px; 63 | } 64 | 65 | .period { 66 | display: block; 67 | font-style: italic; 68 | } 69 | 70 | /* Footer Styles */ 71 | 72 | footer { 73 | margin: 50px 0; 74 | } 75 | 76 | /* Responsive Styles */ 77 | 78 | @media(max-width:991px) { 79 | .customer-img, 80 | .img-related { 81 | margin-bottom: 30px; 82 | } 83 | } 84 | 85 | @media(max-width:767px) { 86 | .img-portfolio { 87 | margin-bottom: 15px; 88 | } 89 | 90 | header.carousel .carousel { 91 | height: 70%; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

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

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /app/views/pages/_resources_machine_learning.html.haml: -------------------------------------------------------------------------------- 1 | .container 2 | .row 3 | .col-md-3 4 | %h1.page-header 5 | Machine Learning Resources 6 | -#%small Helpful Links 7 | .row 8 | .col-md-3 9 | .list-group 10 | = link_to 'Review of the linear algebra concepts relevant to machine learning', "http://www.deeplearningbook.org/contents/linear_algebra.html", class: 'list-group-item', target: '_blank' 11 | = link_to 'Free online book for Neural Networks and Deep Learning', "http://neuralnetworksanddeeplearning.com", class: 'list-group-item', target: '_blank' 12 | = link_to 'An Introduction to Statistical Learning (Book and MOOC slides', "http://www-bcf.usc.edu/~gareth/ISL/", class: 'list-group-item', target: '_blank' 13 | = link_to 'Every single Machine Learning course on the internet, ranked by your reviews', "https://medium.freecodecamp.org/every-single-machine-learning-course-on-the-internet-ranked-by-your-reviews-3c4a7b8026c0", class: 'list-group-item', target: '_blank' 14 | = link_to 'Deep Learning Book, a.k.a. the Bible of Deep Learning, authored by Ian Goodfellow, Yoshua Bengio, and Aaron Courville', "http://www.deeplearningbook.org/", class: 'list-group-item', target: '_blank' 15 | = link_to 'Machine learning algo cheat sheet', "https://docs.microsoft.com/en-us/azure/machine-learning/studio/algorithm-cheat-sheet", class: 'list-group-item', target: '_blank' 16 | = link_to 'Neural Networks and Deep Learning (free online book)', "http://neuralnetworksanddeeplearning.com/", class: 'list-group-item', target: '_blank' 17 | = link_to 'List of free, open source books on machine learning, stats, data-mining, etc.', "https://github.com/josephmisiti/awesome-machine-learning/blob/master/books.md", class: 'list-group-item', target: '_blank' 18 | = link_to 'Another Book List', "https://elitedatascience.com/books", class: 'list-group-item', target: '_blank' -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # PostgreSQL. Versions 8.2 and up are supported. 2 | # 3 | # Install the pg driver: 4 | # gem install pg 5 | # On Mac OS X with macports: 6 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config 7 | # On Windows: 8 | # gem install pg 9 | # Choose the win32 build. 10 | # Install PostgreSQL and put its /bin directory on your path. 11 | # 12 | # Configure Using Gemfile 13 | # gem 'pg' 14 | # 15 | development: 16 | adapter: postgresql 17 | host: localhost 18 | encoding: unicode 19 | database: bitparrot_development 20 | pool: 5 21 | username: bitparrot 22 | password: 23 | template: template0 24 | 25 | # Connect on a TCP socket. Omitted by default since the client uses a 26 | # domain socket that doesn't need configuration. Windows does not have 27 | # domain sockets, so uncomment these lines. 28 | #host: localhost 29 | #port: 5432 30 | 31 | # Schema search path. The server defaults to $user,public 32 | #schema_search_path: myapp,sharedapp,public 33 | 34 | # Minimum log levels, in increasing order: 35 | # debug5, debug4, debug3, debug2, debug1, 36 | # log, notice, warning, error, fatal, and panic 37 | # The server defaults to notice. 38 | #min_messages: warning 39 | 40 | # Warning: The database defined as "test" will be erased and 41 | # re-generated from your development database when you run "rake". 42 | # Do not set this db to the same as development or production. 43 | test: 44 | adapter: postgresql 45 | host: localhost 46 | encoding: unicode 47 | database: bitparrot_test 48 | pool: 5 49 | username: bitparrot 50 | password: 51 | template: template0 52 | 53 | production: 54 | adapter: postgresql 55 | host: localhost 56 | encoding: unicode 57 | database: bitparrot_production 58 | pool: 5 59 | username: bitparrot 60 | password: 61 | template: template0 62 | -------------------------------------------------------------------------------- /app/assets/stylesheets/1st_load_framework.css.scss: -------------------------------------------------------------------------------- 1 | // import the CSS framework 2 | @import "bootstrap-sprockets"; 3 | @import "bootstrap"; 4 | 5 | // make all images responsive by default 6 | img { 7 | @extend .img-responsive; 8 | margin: 0 auto; 9 | } 10 | // override for the 'Home' navigation link 11 | .navbar-brand { 12 | font-size: inherit; 13 | } 14 | 15 | // THESE ARE EXAMPLES YOU CAN MODIFY 16 | // create your own classes 17 | // to make views framework-neutral 18 | .column { 19 | @extend .col-md-6; 20 | @extend .text-center; 21 | } 22 | .form { 23 | @extend .col-md-6; 24 | } 25 | .form-centered { 26 | @extend .col-md-6; 27 | @extend .text-center; 28 | } 29 | .submit { 30 | @extend .btn; 31 | @extend .btn-primary; 32 | @extend .btn-lg; 33 | } 34 | // apply styles to HTML elements 35 | // to make views framework-neutral 36 | main { 37 | @extend .container; 38 | background-color: #eee; 39 | padding-bottom: 80px; 40 | width: 100%; 41 | margin-top: 51px; // accommodate the navbar 42 | } 43 | section { 44 | @extend .row; 45 | margin-top: 20px; 46 | } 47 | 48 | // Styles for form views 49 | // using Bootstrap 3 50 | // generated by the rails_layout gem 51 | .authform { 52 | padding-top: 30px; 53 | max-width: 320px; 54 | margin: 0 auto; 55 | } 56 | .authform form { 57 | @extend .well; 58 | @extend .well-lg; 59 | padding-bottom: 40px; 60 | } 61 | .authform .right { 62 | float: right !important; 63 | } 64 | .authform .button { 65 | @extend .btn; 66 | @extend .btn-primary; 67 | } 68 | .authform fieldset { 69 | @extend .well; 70 | } 71 | #error_explanation:not(:empty) { 72 | @extend .alert; 73 | @extend .alert-danger; 74 | } 75 | #error_explanation h2 { 76 | font-size: 16px; 77 | } 78 | .button-xs { 79 | @extend .btn; 80 | @extend .btn-primary; 81 | @extend .btn-xs; 82 | } 83 | 84 | .navbar-default { 85 | background-color: #f59335; 86 | border-color: #e1eef3; 87 | } 88 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.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 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure public file server for tests with Cache-Control for performance. 16 | config.public_file_server.enabled = true 17 | config.public_file_server.headers = { 18 | 'Cache-Control' => 'public, max-age=3600' 19 | } 20 | 21 | # Show full error reports and disable caching. 22 | config.consider_all_requests_local = true 23 | config.action_controller.perform_caching = false 24 | 25 | # Raise exceptions instead of rendering exception templates. 26 | config.action_dispatch.show_exceptions = false 27 | 28 | # Disable request forgery protection in test environment. 29 | config.action_controller.allow_forgery_protection = false 30 | config.action_mailer.perform_caching = false 31 | 32 | # Tell Action Mailer not to deliver emails to the real world. 33 | # The :test delivery method accumulates sent emails in the 34 | # ActionMailer::Base.deliveries array. 35 | config.action_mailer.delivery_method = :test 36 | config.action_mailer.default_url_options = { :host => Rails.application.secrets.domain_name } 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /spec/features/users/sign_in_spec.rb: -------------------------------------------------------------------------------- 1 | # Feature: Sign in 2 | # As a user 3 | # I want to sign in 4 | # So I can visit protected areas of the site 5 | feature 'Sign in', :devise do 6 | 7 | # Scenario: User cannot sign in if not registered 8 | # Given I do not exist as a user 9 | # When I sign in with valid credentials 10 | # Then I see an invalid credentials message 11 | scenario 'user cannot sign in if not registered' do 12 | signin('test@example.com', 'please123') 13 | expect(page).to have_content I18n.t 'devise.failure.not_found_in_database', authentication_keys: 'email' 14 | end 15 | 16 | # Scenario: User can sign in with valid credentials 17 | # Given I exist as a user 18 | # And I am not signed in 19 | # When I sign in with valid credentials 20 | # Then I see a success message 21 | scenario 'user can sign in with valid credentials' do 22 | user = FactoryGirl.create(:user) 23 | signin(user.email, user.password) 24 | expect(page).to have_content I18n.t 'devise.sessions.signed_in' 25 | end 26 | 27 | # Scenario: User cannot sign in with wrong email 28 | # Given I exist as a user 29 | # And I am not signed in 30 | # When I sign in with a wrong email 31 | # Then I see an invalid email message 32 | scenario 'user cannot sign in with wrong email' do 33 | user = FactoryGirl.create(:user) 34 | signin('invalid@email.com', user.password) 35 | expect(page).to have_content I18n.t 'devise.failure.not_found_in_database', authentication_keys: 'email' 36 | end 37 | 38 | # Scenario: User cannot sign in with wrong password 39 | # Given I exist as a user 40 | # And I am not signed in 41 | # When I sign in with a wrong password 42 | # Then I see an invalid password message 43 | scenario 'user cannot sign in with wrong password' do 44 | user = FactoryGirl.create(:user) 45 | signin(user.email, 'invalidpass') 46 | expect(page).to have_content I18n.t 'devise.failure.invalid', authentication_keys: 'email' 47 | end 48 | 49 | end 50 | -------------------------------------------------------------------------------- /app/views/pages/404.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | 404 8 | %small Page Not Found 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active 404 13 | / /.row 14 | .row 15 | .col-lg-12 16 | .jumbotron 17 | %h1 18 | %span.error-404 404 19 | %p The page you're looking for could not be found. Here are some helpful links to get you back on track: 20 | %ul 21 | %li 22 | = link_to 'Home', root_path 23 | %li 24 | = link_to 'About', page_path('about') 25 | %li 26 | = link_to 'Services', page_path('services') 27 | %li 28 | = link_to 'Contact', page_path('contact') 29 | %li 30 | Portfolio 31 | %ul 32 | %li 33 | = link_to '1 Column Portfolio', page_path('portfolio-1-col') 34 | %li 35 | = link_to '2 Column Portfolio', page_path('portfolio-2-col') 36 | %li 37 | = link_to '3 Column Portfolio', page_path('portfolio-3-col') 38 | %li 39 | = link_to '4 Column Portfolio', page_path('portfolio-4-col') 40 | %li 41 | Blog 42 | %ul 43 | %li 44 | = link_to 'Blog Home 1', page_path('blog-home-1') 45 | %li 46 | = link_to 'Blog Home 2', page_path('blog-home-2') 47 | %li 48 | = link_to 'Blog Post', page_path('blog-post') 49 | %li 50 | Other Pages 51 | %ul 52 | %li 53 | = link_to 'Full Width Page', page_path('full-width') 54 | %li 55 | = link_to 'Sidebar Page', page_path('sidebar') 56 | %li 57 | = link_to 'FAQ', page_path('faq') 58 | %li 59 | = link_to '404', page_path('404') 60 | %li 61 | = link_to 'Pricing Table', page_path('pricing') 62 | / /.container 63 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum, this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests, default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. If you use this option 30 | # you need to make sure to reconnect any threads in the `on_worker_boot` 31 | # block. 32 | # 33 | # preload_app! 34 | 35 | # The code in the `on_worker_boot` will be called if you are using 36 | # clustered mode by specifying a number of `workers`. After each worker 37 | # process is booted this block will be run, if you are using `preload_app!` 38 | # option you will want to use this block to reconnect to any threads 39 | # or connections that may have been created at application boot, Ruby 40 | # cannot share connections between processes. 41 | # 42 | # on_worker_boot do 43 | # ActiveRecord::Base.establish_connection if defined?(ActiveRecord) 44 | # end 45 | 46 | # Allow puma to be restarted by `rails restart` command. 47 | plugin :tmp_restart 48 | -------------------------------------------------------------------------------- /app/views/pages/sidebar.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Sidebar Page 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Sidebar Page 13 | / /.row 14 | / Content Row 15 | .row 16 | / Sidebar Column 17 | .col-md-3 18 | .list-group 19 | = link_to 'Home', root_path, class: 'list-group-item' 20 | = link_to 'About', page_path('about'), class: 'list-group-item' 21 | = link_to 'Services', page_path('services'), class: 'list-group-item' 22 | = link_to 'Contact', page_path('contact'), class: 'list-group-item' 23 | = link_to '1 Column Portfolio', page_path('portfolio-1-col'), class: 'list-group-item' 24 | = link_to '2 Column Portfolio', page_path('portfolio-2-col'), class: 'list-group-item' 25 | = link_to '3 Column Portfolio', page_path('portfolio-3-col'), class: 'list-group-item' 26 | = link_to '4 Column Portfolio', page_path('portfolio-4-col'), class: 'list-group-item' 27 | = link_to 'Single Portfolio Item', page_path('portfolio-item'), class: 'list-group-item' 28 | = link_to 'Blog Home 1', page_path('blog-home-1'), class: 'list-group-item' 29 | = link_to 'Blog Home 2', page_path('blog-home-2'), class: 'list-group-item' 30 | = link_to 'Blog Post', page_path('blog-post'), class: 'list-group-item' 31 | = link_to 'Full Width Page', page_path('full-width'), class: 'list-group-item' 32 | = link_to 'Sidebar Page', page_path('sidebar'), class: 'list-group-item' 33 | = link_to 'FAQ', page_path('faq'), class: 'list-group-item' 34 | = link_to '404', page_path('404'), class: 'list-group-item' 35 | = link_to 'Pricing Table', page_path('pricing'), class: 'list-group-item' 36 | / Content Column 37 | .col-md-9 38 | %h2 Section Heading 39 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Soluta, et temporibus, facere perferendis veniam beatae non debitis, numquam blanditiis necessitatibus vel mollitia dolorum laudantium, voluptate dolores iure maxime ducimus fugit. 40 | / /.row 41 | / /.container 42 | -------------------------------------------------------------------------------- /app/views/pages/faq.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | FAQ 8 | %small 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active FAQ 13 | / /.row 14 | / Content Row 15 | .row 16 | .col-lg-12 17 | #accordion.panel-group 18 | .panel.panel-default 19 | .panel-heading 20 | %h4.panel-title 21 | %a.accordion-toggle{"data-parent" => "#accordion", "data-toggle" => "collapse", :href => "#collapseOne"} Is this an independent site? 22 | #collapseOne.panel-collapse.collapse 23 | .panel-body 24 | Yes, this site is run by independent developers. We're not pushing any agenda from any big corporation. 25 | / /.panel 26 | .panel.panel-default 27 | .panel-heading 28 | %h4.panel-title 29 | %a.accordion-toggle{"data-parent" => "#accordion", "data-toggle" => "collapse", :href => "#collapseTwo"} How do you decide what content to display? 30 | #collapseTwo.panel-collapse.collapse 31 | .panel-body 32 | We include content that is interesting to us as developers, and content that other developers have asked us to include. 33 | / /.panel 34 | .panel.panel-default 35 | .panel-heading 36 | %h4.panel-title 37 | %a.accordion-toggle{"data-parent" => "#accordion", "data-toggle" => "collapse", :href => "#collapseThree"} Where can I suggest some data to include in this site? 38 | #collapseThree.panel-collapse.collapse 39 | .panel-body 40 | We would love to hear your suggestions. Please tweet any ideas to us @Bit-Parrot. 41 | / /.panel 42 | .panel.panel-default 43 | .panel-heading 44 | %h4.panel-title 45 | %a.accordion-toggle{"data-parent" => "#accordion", "data-toggle" => "collapse", :href => "#collapseFour"} How did you come up with the name Bit Parrot and what does it refer to? 46 | #collapseFour.panel-collapse.collapse 47 | .panel-body 48 | Bit Parrot refers to the nature of this site which takes information (bits) and repeats them back to you (like a Parrot). 49 | / /.panel 50 | / /.panel-group 51 | / /.col-lg-12 52 | / /.row 53 | / /.container 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BitParrot.co 2 | 3 | This is the code for the website 4 | [BitParrot.co](http://www.bitparrot.co/). 5 | 6 | I conceived, designed, and built this myself. I did it because I was tired of tracking all the "bits" I needed to track in separate places so I built this "parrot" that does it for me. 7 | 8 | ## Getting Started 9 | 10 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system. 11 | 12 | ### Prerequisites 13 | 14 | - Postgres (OSX users can run `brew install postgresql`) 15 | - bundler (`gem install bundler`) 16 | - Ruby 2.3.1 (or whatever version this app is currently using, check the Gemfile) 17 | - Any environment variables you prefer to setup and use. 18 | 19 | ### Installing 20 | 21 | - `bundle install` 22 | - (start your Postgres db) 23 | - `rake db:create` (TODO: create seed data) 24 | - (remember to migrate which in a Rails 5 app is `raila db:migrate`) 25 | 26 | To create an initial admin user, fire up `rails c` and do the following: 27 | 28 | u = User.create(username: "Whatever", password: "foo123456", email: "me@domain.org", password_confirmation: "foo123456") 29 | u.activate! 30 | u.is_admin = true 31 | u.save 32 | 33 | ### Running the server 34 | 35 | - `rails s` 36 | 37 | ## Running the tests 38 | 39 | There are pre-seeded rspec tests. To run these it is 'rspec spec' from your command line. 40 | 41 | ### More about the tests 42 | 43 | These pre-seeded tests include feature, model, and policy tests. See the RSpec folder for details. 44 | 45 | ## Deployment 46 | 47 | Since this is a Ruby application, deploying it to Heroku is easy. 48 | * [Getting Started on Heroku with Ruby](https://devcenter.heroku.com/articles/getting-started-with-ruby#deploy-the-app) - Here is a good step by step from Heroku. 49 | 50 | ## Built With 51 | 52 | - Ruby 53 | - Rails 5 54 | - HAML 55 | 56 | And the usual suspects including: 57 | - Html 58 | - CSS 59 | - Javascript 60 | 61 | ## Contributing 62 | 63 | This was built my Michelle Bonat. It's not currently open for contributions, but I would love to hear any comments and suggestions about how you have modified this code. 64 | Contact me through the methods noted below. 65 | 66 | ## Authors 67 | 68 | * **Michelle Bonat** - *Initial work* - Contact me through [michellebonat.com](http://michellebonat.com/) or on [GitHub](https://github.com/michellebonat) 69 | 70 | ## License 71 | 72 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 73 | 74 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # Note that this schema.rb definition is the authoritative source for your 6 | # database schema. If you need to create the application database on another 7 | # system, you should be using db:schema:load, not running all the migrations 8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 9 | # you'll amass, the slower it'll run and the greater likelihood for issues). 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema.define(version: 20170322002313) do 14 | 15 | # These are extensions that must be enabled in order to support this database 16 | enable_extension "plpgsql" 17 | 18 | create_table "users", force: :cascade do |t| 19 | t.string "email", default: "", null: false 20 | t.string "encrypted_password", default: "", null: false 21 | t.string "reset_password_token" 22 | t.datetime "reset_password_sent_at" 23 | t.datetime "remember_created_at" 24 | t.integer "sign_in_count", default: 0, null: false 25 | t.datetime "current_sign_in_at" 26 | t.datetime "last_sign_in_at" 27 | t.inet "current_sign_in_ip" 28 | t.inet "last_sign_in_ip" 29 | t.datetime "created_at", null: false 30 | t.datetime "updated_at", null: false 31 | t.string "name" 32 | t.string "confirmation_token" 33 | t.datetime "confirmed_at" 34 | t.datetime "confirmation_sent_at" 35 | t.string "unconfirmed_email" 36 | t.integer "role" 37 | t.string "invitation_token" 38 | t.datetime "invitation_created_at" 39 | t.datetime "invitation_sent_at" 40 | t.datetime "invitation_accepted_at" 41 | t.integer "invitation_limit" 42 | t.string "invited_by_type" 43 | t.integer "invited_by_id" 44 | t.integer "invitations_count", default: 0 45 | t.index ["email"], name: "index_users_on_email", unique: true, using: :btree 46 | t.index ["invitation_token"], name: "index_users_on_invitation_token", unique: true, using: :btree 47 | t.index ["invitations_count"], name: "index_users_on_invitations_count", using: :btree 48 | t.index ["invited_by_id"], name: "index_users_on_invited_by_id", using: :btree 49 | t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /app/views/pages/portfolio-item.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Portfolio Item 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Portfolio Item 13 | / /.row 14 | / Portfolio Item Row 15 | .row 16 | .col-md-8 17 | #carousel-example-generic.carousel.slide{"data-ride" => "carousel"} 18 | / Indicators 19 | %ol.carousel-indicators 20 | %li.active{"data-slide-to" => "0", "data-target" => "#carousel-example-generic"} 21 | %li{"data-slide-to" => "1", "data-target" => "#carousel-example-generic"} 22 | %li{"data-slide-to" => "2", "data-target" => "#carousel-example-generic"} 23 | / Wrapper for slides 24 | .carousel-inner 25 | .item.active 26 | %img.img-responsive{:alt => "", :src => "http://placehold.it/750x500"}/ 27 | .item 28 | %img.img-responsive{:alt => "", :src => "http://placehold.it/750x500"}/ 29 | .item 30 | %img.img-responsive{:alt => "", :src => "http://placehold.it/750x500"}/ 31 | / Controls 32 | %a.left.carousel-control{"data-slide" => "prev", :href => "#carousel-example-generic"} 33 | %span.glyphicon.glyphicon-chevron-left 34 | %a.right.carousel-control{"data-slide" => "next", :href => "#carousel-example-generic"} 35 | %span.glyphicon.glyphicon-chevron-right 36 | .col-md-4 37 | %h3 Project Description 38 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. Sed dui lorem, adipiscing in adipiscing et, interdum nec metus. Mauris ultricies, justo eu convallis placerat, felis enim. 39 | %h3 Project Details 40 | %ul 41 | %li Lorem Ipsum 42 | %li Dolor Sit Amet 43 | %li Consectetur 44 | %li Adipiscing Elit 45 | / /.row 46 | / Related Projects Row 47 | .row 48 | .col-lg-12 49 | %h3.page-header Related Projects 50 | .col-sm-3.col-xs-6 51 | %a{:href => "#"} 52 | %img.img-responsive.img-hover.img-related{:alt => "", :src => "http://placehold.it/500x300"}/ 53 | .col-sm-3.col-xs-6 54 | %a{:href => "#"} 55 | %img.img-responsive.img-hover.img-related{:alt => "", :src => "http://placehold.it/500x300"}/ 56 | .col-sm-3.col-xs-6 57 | %a{:href => "#"} 58 | %img.img-responsive.img-hover.img-related{:alt => "", :src => "http://placehold.it/500x300"}/ 59 | .col-sm-3.col-xs-6 60 | %a{:href => "#"} 61 | %img.img-responsive.img-hover.img-related{:alt => "", :src => "http://placehold.it/500x300"}/ 62 | / /.row 63 | / /.container 64 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.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 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports. 13 | config.consider_all_requests_local = true 14 | 15 | # Enable/disable caching. By default caching is disabled. 16 | if Rails.root.join('tmp/caching-dev.txt').exist? 17 | config.action_controller.perform_caching = true 18 | 19 | config.cache_store = :memory_store 20 | config.public_file_server.headers = { 21 | 'Cache-Control' => 'public, max-age=172800' 22 | } 23 | else 24 | config.action_controller.perform_caching = false 25 | 26 | config.cache_store = :null_store 27 | end 28 | 29 | # Don't care if the mailer can't send. 30 | config.action_mailer.raise_delivery_errors = false 31 | 32 | config.action_mailer.perform_caching = false 33 | 34 | # Print deprecation notices to the Rails logger. 35 | config.active_support.deprecation = :log 36 | 37 | # Raise an error on page load if there are pending migrations. 38 | config.active_record.migration_error = :page_load 39 | 40 | # Debug mode disables concatenation and preprocessing of assets. 41 | # This option may cause significant delays in view rendering with a large 42 | # number of complex assets. 43 | config.assets.debug = true 44 | 45 | config.action_mailer.smtp_settings = { 46 | address: "smtp.sendgrid.net", 47 | port: 587, 48 | domain: Rails.application.secrets.domain_name, 49 | authentication: "plain", 50 | enable_starttls_auto: true, 51 | user_name: Rails.application.secrets.email_provider_username, 52 | password: Rails.application.secrets.email_provider_password 53 | } 54 | # ActionMailer Config 55 | config.action_mailer.default_url_options = { :host => 'localhost:3000' } 56 | config.action_mailer.delivery_method = :smtp 57 | config.action_mailer.raise_delivery_errors = true 58 | # Send email in development mode? 59 | config.action_mailer.perform_deliveries = true 60 | 61 | 62 | # Suppress logger output for asset requests. 63 | config.assets.quiet = true 64 | 65 | # Raises error for missing translations 66 | # config.action_view.raise_on_missing_translations = true 67 | 68 | # Use an evented file watcher to asynchronously detect changes in source code, 69 | # routes, locales, etc. This feature depends on the listen gem. 70 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 71 | end 72 | -------------------------------------------------------------------------------- /spec/features/visitors/sign_up_spec.rb: -------------------------------------------------------------------------------- 1 | # Feature: Sign up 2 | # As a visitor 3 | # I want to sign up 4 | # So I can visit protected areas of the site 5 | feature 'Sign Up', :devise do 6 | 7 | # Scenario: Visitor can sign up with valid email address and password 8 | # Given I am not signed in 9 | # When I sign up with a valid email address and password 10 | # Then I see a successful sign up message 11 | scenario 'visitor can sign up with valid email address and password' do 12 | sign_up_with('test@example.com', 'please123', 'please123') 13 | txts = [I18n.t( 'devise.registrations.signed_up'), I18n.t( 'devise.registrations.signed_up_but_unconfirmed')] 14 | expect(page).to have_content(/.*#{txts[0]}.*|.*#{txts[1]}.*/) 15 | end 16 | 17 | # Scenario: Visitor cannot sign up with invalid email address 18 | # Given I am not signed in 19 | # When I sign up with an invalid email address 20 | # Then I see an invalid email message 21 | scenario 'visitor cannot sign up with invalid email address' do 22 | sign_up_with('bogus', 'please123', 'please123') 23 | expect(page).to have_content 'Email is invalid' 24 | end 25 | 26 | # Scenario: Visitor cannot sign up without password 27 | # Given I am not signed in 28 | # When I sign up without a password 29 | # Then I see a missing password message 30 | scenario 'visitor cannot sign up without password' do 31 | sign_up_with('test@example.com', '', '') 32 | expect(page).to have_content "Password can't be blank" 33 | end 34 | 35 | # Scenario: Visitor cannot sign up with a short password 36 | # Given I am not signed in 37 | # When I sign up with a short password 38 | # Then I see a 'too short password' message 39 | scenario 'visitor cannot sign up with a short password' do 40 | sign_up_with('test@example.com', 'please', 'please') 41 | expect(page).to have_content "Password is too short" 42 | end 43 | 44 | # Scenario: Visitor cannot sign up without password confirmation 45 | # Given I am not signed in 46 | # When I sign up without a password confirmation 47 | # Then I see a missing password confirmation message 48 | scenario 'visitor cannot sign up without password confirmation' do 49 | sign_up_with('test@example.com', 'please123', '') 50 | expect(page).to have_content "Password confirmation doesn't match" 51 | end 52 | 53 | # Scenario: Visitor cannot sign up with mismatched password and confirmation 54 | # Given I am not signed in 55 | # When I sign up with a mismatched password confirmation 56 | # Then I should see a mismatched password message 57 | scenario 'visitor cannot sign up with mismatched password and confirmation' do 58 | sign_up_with('test@example.com', 'please123', 'mismatch') 59 | expect(page).to have_content "Password confirmation doesn't match" 60 | end 61 | 62 | end 63 | -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV['RAILS_ENV'] ||= 'test' 3 | require File.expand_path('../../config/environment', __FILE__) 4 | # Prevent database truncation if the environment is production 5 | abort("The Rails environment is running in production mode!") if Rails.env.production? 6 | require 'spec_helper' 7 | require 'rspec/rails' 8 | # Add additional requires below this line. Rails is not loaded until this point! 9 | 10 | # Requires supporting ruby files with custom matchers and macros, etc, in 11 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are 12 | # run as spec files by default. This means that files in spec/support that end 13 | # in _spec.rb will both be required and run as specs, causing the specs to be 14 | # run twice. It is recommended that you do not name files matching this glob to 15 | # end with _spec.rb. You can configure this pattern with the --pattern 16 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. 17 | # 18 | # The following line is provided for convenience purposes. It has the downside 19 | # of increasing the boot-up time by auto-requiring all files in the support 20 | # directory. Alternatively, in the individual `*_spec.rb` files, manually 21 | # require only the support files necessary. 22 | # 23 | Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } 24 | 25 | # Checks for pending migration and applies them before tests are run. 26 | # If you are not using ActiveRecord, you can remove this line. 27 | ActiveRecord::Migration.maintain_test_schema! 28 | 29 | RSpec.configure do |config| 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 = false 37 | 38 | # RSpec Rails can automatically mix in different behaviours to your tests 39 | # based on their file location, for example enabling you to call `get` and 40 | # `post` in specs under `spec/controllers`. 41 | # 42 | # You can disable this behaviour by removing the line below, and instead 43 | # explicitly tag your specs with their type, e.g.: 44 | # 45 | # RSpec.describe UsersController, :type => :controller do 46 | # # ... 47 | # end 48 | # 49 | # The different available types are documented in the features, such as in 50 | # https://relishapp.com/rspec/rspec-rails/docs 51 | config.infer_spec_type_from_file_location! 52 | 53 | # Filter lines from Rails gems in backtraces. 54 | config.filter_rails_from_backtrace! 55 | # arbitrary gems may also be filtered via: 56 | # config.filter_gems_from_backtrace("gem name") 57 | end 58 | -------------------------------------------------------------------------------- /app/views/pages/portfolio-4-col.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Four Column Portfolio 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Four Column Portfolio 13 | / /.row 14 | / Projects Row 15 | .row 16 | .col-md-3.img-portfolio 17 | = link_to page_path('portfolio-item') do 18 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 19 | .col-md-3.img-portfolio 20 | = link_to page_path('portfolio-item') do 21 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 22 | .col-md-3.img-portfolio 23 | = link_to page_path('portfolio-item') do 24 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 25 | .col-md-3.img-portfolio 26 | = link_to page_path('portfolio-item') do 27 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 28 | / /.row 29 | / Projects Row 30 | .row 31 | .col-md-3.img-portfolio 32 | = link_to page_path('portfolio-item') do 33 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 34 | .col-md-3.img-portfolio 35 | = link_to page_path('portfolio-item') do 36 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 37 | .col-md-3.img-portfolio 38 | = link_to page_path('portfolio-item') do 39 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 40 | .col-md-3.img-portfolio 41 | = link_to page_path('portfolio-item') do 42 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 43 | / /.row 44 | / Projects Row 45 | .row 46 | .col-md-3.img-portfolio 47 | = link_to page_path('portfolio-item') do 48 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 49 | .col-md-3.img-portfolio 50 | = link_to page_path('portfolio-item') do 51 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 52 | .col-md-3.img-portfolio 53 | = link_to page_path('portfolio-item') do 54 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 55 | .col-md-3.img-portfolio 56 | = link_to page_path('portfolio-item') do 57 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/750x450"}/ 58 | / /.row 59 | %hr/ 60 | / Pagination 61 | .row.text-center 62 | .col-lg-12 63 | %ul.pagination 64 | %li 65 | %a{:href => "#"} « 66 | %li.active 67 | %a{:href => "#"} 1 68 | %li 69 | %a{:href => "#"} 2 70 | %li 71 | %a{:href => "#"} 3 72 | %li 73 | %a{:href => "#"} 4 74 | %li 75 | %a{:href => "#"} 5 76 | %li 77 | %a{:href => "#"} » 78 | / /.row 79 | / /.container 80 | -------------------------------------------------------------------------------- /app/views/pages/contact.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Contact 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Contact 13 | / /.row 14 | / Content Row 15 | .row 16 | / Map Column 17 | .col-md-8 18 | / Embedded Google Map 19 | %iframe{:frameborder => "0", :height => "400px", :marginheight => "0", :marginwidth => "0", :scrolling => "no", :src => "http://maps.google.com/maps?hl=en&ie=UTF8&ll=37.0625,-95.677068&spn=56.506174,79.013672&t=m&z=4&output=embed", :width => "100%"} 20 | / Contact Details Column 21 | .col-md-4 22 | %h3 Contact Details 23 | %p 24 | 3481 Melrose Place 25 | %br>/ 26 | Beverly Hills, CA 90210 27 | %br/ 28 | %p 29 | %i.fa.fa-phone 30 | = succeed ":" do 31 | %abbr{:title => "Phone"} P 32 | %p 33 | %i.fa.fa-envelope-o 34 | = succeed ":" do 35 | %abbr{:title => "Email"} E 36 | %a{:href => "mailto:name@example.com"} name@example.com 37 | %p 38 | %i.fa.fa-clock-o 39 | = succeed ":" do 40 | %abbr{:title => "Hours"} H 41 | %ul.list-unstyled.list-inline.list-social-icons 42 | %li 43 | %a{:href => "#"} 44 | %i.fa.fa-facebook-square.fa-2x 45 | %li 46 | %a{:href => "#"} 47 | %i.fa.fa-linkedin-square.fa-2x 48 | %li 49 | %a{:href => "#"} 50 | %i.fa.fa-twitter-square.fa-2x 51 | %li 52 | %a{:href => "#"} 53 | %i.fa.fa-google-plus-square.fa-2x 54 | / /.row 55 | / Contact Form 56 | .row 57 | .col-md-8 58 | %h3 Send us a Message 59 | %form#contactForm{:name => "sentMessage", :novalidate => ""} 60 | .control-group.form-group 61 | .controls 62 | %label Full Name: 63 | %input#name.form-control{"data-validation-required-message" => "Please enter your name.", :required => "", :type => "text"}/ 64 | %p.help-block 65 | .control-group.form-group 66 | .controls 67 | %label Phone Number: 68 | %input#phone.form-control{"data-validation-required-message" => "Please enter your phone number.", :required => "", :type => "tel"}/ 69 | .control-group.form-group 70 | .controls 71 | %label Email Address: 72 | %input#email.form-control{"data-validation-required-message" => "Please enter your email address.", :required => "", :type => "email"}/ 73 | .control-group.form-group 74 | .controls 75 | %label Message: 76 | %textarea#message.form-control{:cols => "100", "data-validation-required-message" => "Please enter your message", :maxlength => "999", :required => "", :rows => "10", :style => "resize:none"} 77 | #success 78 | / For success/fail messages 79 | %button.btn.btn-primary{:type => "submit"} Send Message 80 | / /.row 81 | / /.container 82 | -------------------------------------------------------------------------------- /app/views/pages/pricing.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Pricing Table 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Pricing Table 13 | / /.row 14 | / Content Row 15 | .row 16 | .col-md-4 17 | .panel.panel-default.text-center 18 | .panel-heading 19 | %h3.panel-title Basic 20 | .panel-body 21 | %span.price 22 | %sup> $ 23 | 19 24 | %sup 99 25 | %span.period per month 26 | %ul.list-group 27 | %li.list-group-item 28 | %strong 1 29 | User 30 | %li.list-group-item 31 | %strong 5 32 | Projects 33 | %li.list-group-item 34 | %strong Unlimited 35 | Email Accounts 36 | %li.list-group-item 37 | %strong 10GB 38 | Disk Space 39 | %li.list-group-item 40 | %strong 100GB 41 | Monthly Bandwidth 42 | %li.list-group-item 43 | %a.btn.btn-primary{:href => "#"} Sign Up! 44 | .col-md-4 45 | .panel.panel-primary.text-center 46 | .panel-heading 47 | %h3.panel-title 48 | Plus 49 | %span.label.label-success Best Value 50 | .panel-body 51 | %span.price 52 | %sup> $ 53 | 39 54 | %sup 99 55 | %span.period per month 56 | %ul.list-group 57 | %li.list-group-item 58 | %strong 10 59 | User 60 | %li.list-group-item 61 | %strong 500 62 | Projects 63 | %li.list-group-item 64 | %strong Unlimited 65 | Email Accounts 66 | %li.list-group-item 67 | %strong 1000GB 68 | Disk Space 69 | %li.list-group-item 70 | %strong 10000GB 71 | Monthly Bandwidth 72 | %li.list-group-item 73 | %a.btn.btn-primary{:href => "#"} Sign Up! 74 | .col-md-4 75 | .panel.panel-default.text-center 76 | .panel-heading 77 | %h3.panel-title Ultra 78 | .panel-body 79 | %span.price 80 | %sup> $ 81 | 159 82 | %sup 99 83 | %span.period per month 84 | %ul.list-group 85 | %li.list-group-item 86 | %strong Unlimted 87 | Users 88 | %li.list-group-item 89 | %strong Unlimited 90 | Projects 91 | %li.list-group-item 92 | %strong Unlimited 93 | Email Accounts 94 | %li.list-group-item 95 | %strong 10000GB 96 | Disk Space 97 | %li.list-group-item 98 | %strong Unlimited 99 | Monthly Bandwidth 100 | %li.list-group-item 101 | %a.btn.btn-primary{:href => "#"} Sign Up! 102 | / /.row 103 | / /.container 104 | -------------------------------------------------------------------------------- /app/views/pages/portfolio-2-col.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Two Column Portfolio 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Two Column Portfolio 13 | / /.row 14 | / Projects Row 15 | .row 16 | .col-md-6.img-portfolio 17 | = link_to page_path('portfolio-item') do 18 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 19 | %h3 20 | = link_to 'Project', page_path('portfolio-item') 21 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 22 | .col-md-6.img-portfolio 23 | = link_to page_path('portfolio-item') do 24 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 25 | %h3 26 | = link_to 'Project', page_path('portfolio-item') 27 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 28 | / /.row 29 | / Projects Row 30 | .row 31 | .col-md-6.img-portfolio 32 | = link_to page_path('portfolio-item') do 33 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 34 | %h3 35 | = link_to 'Project', page_path('portfolio-item') 36 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 37 | .col-md-6.img-portfolio 38 | = link_to page_path('portfolio-item') do 39 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 40 | %h3 41 | = link_to 'Project', page_path('portfolio-item') 42 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 43 | / /.row 44 | / Projects Row 45 | .row 46 | .col-md-6.img-portfolio 47 | = link_to page_path('portfolio-item') do 48 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 49 | %h3 50 | = link_to 'Project', page_path('portfolio-item') 51 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 52 | .col-md-6.img-portfolio 53 | = link_to page_path('portfolio-item') do 54 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 55 | %h3 56 | = link_to 'Project', page_path('portfolio-item') 57 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 58 | / /.row 59 | %hr/ 60 | / Pagination 61 | .row.text-center 62 | .col-lg-12 63 | %ul.pagination 64 | %li 65 | %a{:href => "#"} « 66 | %li.active 67 | %a{:href => "#"} 1 68 | %li 69 | %a{:href => "#"} 2 70 | %li 71 | %a{:href => "#"} 3 72 | %li 73 | %a{:href => "#"} 4 74 | %li 75 | %a{:href => "#"} 5 76 | %li 77 | %a{:href => "#"} » 78 | / /.row 79 | / /.container 80 | -------------------------------------------------------------------------------- /app/views/pages/blog-home-2.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | .row 4 | .col-lg-12 5 | %h1.page-header 6 | Blog Home Two 7 | %small Subheading 8 | %ol.breadcrumb 9 | %li 10 | = link_to 'Home', root_path 11 | %li.active Blog Home Two 12 | / /.row 13 | / Blog Post Row 14 | .row 15 | .col-md-1.text-center 16 | %p 17 | %i.fa.fa-camera.fa-4x 18 | %p June 17, 2014 19 | .col-md-5 20 | = link_to page_path('blog-post') do 21 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/600x300"}/ 22 | .col-md-6 23 | %h3 24 | = link_to 'Blog Post Title', page_path('blog-post') 25 | %p 26 | by 27 | %a{:href => "#"} Start Bootstrap 28 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 29 | = link_to page_path('blog-post') do 30 | Read More 31 | %i.fa.fa-angle-right 32 | / /.row 33 | %hr/ 34 | / Blog Post Row 35 | .row 36 | .col-md-1.text-center 37 | %p 38 | %i.fa.fa-film.fa-4x 39 | %p June 17, 2014 40 | .col-md-5 41 | = link_to page_path('blog-post') do 42 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/600x300"}/ 43 | .col-md-6 44 | %h3 45 | = link_to 'Blog Post Title', page_path('blog-post') 46 | %p 47 | by 48 | %a{:href => "#"} Start Bootstrap 49 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 50 | = link_to page_path('blog-post') do 51 | Read More 52 | %i.fa.fa-angle-right 53 | / /.row 54 | %hr/ 55 | / Blog Post Row 56 | .row 57 | .col-md-1.text-center 58 | %p 59 | %i.fa.fa-file-text.fa-4x 60 | %p June 17, 2014 61 | .col-md-5 62 | = link_to page_path('blog-post') do 63 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/600x300"}/ 64 | .col-md-6 65 | %h3 66 | = link_to 'Blog Post Title', page_path('blog-post') 67 | %p 68 | by 69 | %a{:href => "#"} Start Bootstrap 70 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 71 | = link_to page_path('blog-post') do 72 | Read More 73 | %i.fa.fa-angle-right 74 | / /.row 75 | %hr/ 76 | / Pager 77 | .row 78 | %ul.pager 79 | %li.previous 80 | %a{:href => "#"} ← Older 81 | %li.next 82 | %a{:href => "#"} Newer → 83 | / /.row 84 | / /.container 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.gem 3 | *.rbc 4 | /.config 5 | /coverage/ 6 | /InstalledFiles 7 | /pkg/ 8 | /spec/reports/ 9 | /spec/examples.txt 10 | /test/tmp/ 11 | /test/version_tmp/ 12 | /tmp/ 13 | 14 | # Used by dotenv library to load environment variables. 15 | # .env 16 | 17 | ## Specific to RubyMotion: 18 | .dat* 19 | .repl_history 20 | build/ 21 | *.bridgesupport 22 | build-iPhoneOS/ 23 | build-iPhoneSimulator/ 24 | 25 | ## Specific to RubyMotion (use of CocoaPods): 26 | # 27 | # We recommend against adding the Pods directory to your .gitignore. However 28 | # you should judge for yourself, the pros and cons are mentioned at: 29 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 30 | # 31 | # vendor/Pods/ 32 | 33 | ## Documentation cache and generated files: 34 | /.yardoc/ 35 | /_yardoc/ 36 | /doc/ 37 | /rdoc/ 38 | 39 | ## Environment normalization: 40 | /.bundle/ 41 | /vendor/bundle 42 | /lib/bundler/man/ 43 | 44 | # for a library or gem, you might want to ignore these files since the code is 45 | # intended to run in multiple environments; otherwise, check them in: 46 | # Gemfile.lock 47 | # .ruby-version 48 | # .ruby-gemset 49 | 50 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 51 | .rvmrc 52 | ======= 53 | #---------------------------------------------------------------------------- 54 | # Ignore these files when commiting to a git repository. 55 | # 56 | # See http://help.github.com/ignore-files/ for more about ignoring files. 57 | # 58 | # The original version of this file is found here: 59 | # https://github.com/RailsApps/rails-composer/blob/master/files/gitignore.txt 60 | # 61 | # Corrections? Improvements? Create a GitHub issue: 62 | # http://github.com/RailsApps/rails-composer/issues 63 | #---------------------------------------------------------------------------- 64 | 65 | # bundler state 66 | /.bundle 67 | /vendor/bundle/ 68 | /vendor/ruby/ 69 | 70 | # minimal Rails specific artifacts 71 | db/*.sqlite3 72 | /db/*.sqlite3-journal 73 | /log/* 74 | /tmp/* 75 | 76 | # add /config/database.yml if it contains passwords 77 | # /config/database.yml 78 | 79 | # various artifacts 80 | **.war 81 | *.rbc 82 | *.sassc 83 | .redcar/ 84 | .sass-cache 85 | /config/config.yml 86 | /coverage.data 87 | /coverage/ 88 | /db/*.javadb/ 89 | /db/*.sqlite3 90 | /doc/api/ 91 | /doc/app/ 92 | /doc/features.html 93 | /doc/specs.html 94 | /public/cache 95 | /public/stylesheets/compiled 96 | /public/system/* 97 | /spec/tmp/* 98 | /cache 99 | /capybara* 100 | /capybara-*.html 101 | /gems 102 | /specifications 103 | rerun.txt 104 | pickle-email-*.html 105 | .zeus.sock 106 | 107 | # If you find yourself ignoring temporary files generated by your text editor 108 | # or operating system, you probably want to add a global ignore instead: 109 | # git config --global core.excludesfile ~/.gitignore_global 110 | # 111 | # Here are some files you may want to ignore globally: 112 | 113 | # scm revert files 114 | **.orig 115 | 116 | # Mac finder artifacts 117 | .DS_Store 118 | 119 | # Netbeans project directory 120 | /nbproject/ 121 | 122 | # RubyMine project files 123 | .idea 124 | 125 | # Textmate project files 126 | /*.tmproj 127 | 128 | # vim artifacts 129 | **.swp 130 | 131 | # Environment files that may contain sensitive data 132 | .env 133 | .powenv 134 | 135 | # tilde files are usually backup files from a text editor 136 | *~ 137 | 138 | # Ignore application configuration 139 | /config/application.yml 140 | 141 | log/ 142 | -------------------------------------------------------------------------------- /app/views/pages/about.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | About 8 | -#%small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active About 13 | / /.row 14 | / Intro Content 15 | .row 16 | .col-md-6 17 | = link_to image_tag('jumbotron.jpg') 18 | .col-md-6 19 | %h2 About Bit Parrot 20 | %p I created this application to track important information that was in numerous places, and took too much time to stay on top of ... and I also like building apps. So rather than manually tracking all of this nefarious info I created an app to do it for me. You are welcome to use it as well. 21 | %p In the future I plan to create an email that sends out information gathered by the app, so you don't need to go to this site to get updates. 22 | -#= link_to 'Sign Up', new_user_path, target: '_blank' 23 | -#if you would like to keep updated when that is available, and tell us your city and other interests so we can keep those in mind as we build more features. 24 | %p 25 | = link_to "The code is open-sourced see it on GitHub.", "https://github.com/michellebonat/bitparrot" 26 | %p 27 | %p The app uses these nifty things: 28 | %ul.list-inline 29 | %li Ruby on Rails (Rails 5) 30 | %li Bootstrap 3 and Haml, because life is too short to use ERB 31 | %li A nifty template from Hoarrd called Drunken Parrot, for the style and parrot and some images 32 | %li Twitter API, for now 33 | .row 34 | .col-lg-12 35 | %h2.page-header Our Team 36 | .col-md-4.text-center 37 | .thumbnail 38 | = link_to image_tag('Bonat_new_profile_pic_bw_colorburn100.jpg') 39 | .caption 40 | %h3 41 | Michelle Bonat 42 | %br/ 43 | %small Creator 44 | %p Developer, great parking karma. 45 | %ul.list-inline 46 | %li 47 | %a{:href => "https://github.com/michellebonat"} 48 | %i.fa.fa-2x.fa-github-square 49 | %li 50 | %a{:href => "https://www.linkedin.com/in/mbonat"} 51 | %i.fa.fa-2x.fa-linkedin-square 52 | %li 53 | %a{:href => "https://twitter.com/mbonat"} 54 | %i.fa.fa-2x.fa-twitter-square 55 | / /.row 56 | / Our Customers 57 | .row 58 | .col-lg-12 59 | %h2.page-header 60 | Our Sponsors 61 | %p 62 | %small 63 | Blimey! These boxes are blank. Become one of the first sponsors and reach developers. 64 | %p Send us a message on Twitter 65 | %ul.list-inline 66 | %li 67 | %a{:href => "https://twitter.com/bit_parrot"} 68 | %i.fa.fa-2x.fa-twitter-square 69 | -#= link_to 'Contact Us', contact_path, target: '_blank' 70 | .col-md-2.col-sm-4.col-xs-6 71 | %img.img-responsive.customer-img{:alt => "", :src => "http://placehold.it/500x300"}/ 72 | .col-md-2.col-sm-4.col-xs-6 73 | %img.img-responsive.customer-img{:alt => "", :src => "http://placehold.it/500x300"}/ 74 | .col-md-2.col-sm-4.col-xs-6 75 | %img.img-responsive.customer-img{:alt => "", :src => "http://placehold.it/500x300"}/ 76 | .col-md-2.col-sm-4.col-xs-6 77 | %img.img-responsive.customer-img{:alt => "", :src => "http://placehold.it/500x300"}/ 78 | .col-md-2.col-sm-4.col-xs-6 79 | %img.img-responsive.customer-img{:alt => "", :src => "http://placehold.it/500x300"}/ 80 | .col-md-2.col-sm-4.col-xs-6 81 | %img.img-responsive.customer-img{:alt => "", :src => "http://placehold.it/500x300"}/ 82 | / /.row 83 | / /.container 84 | -------------------------------------------------------------------------------- /app/views/pages/portfolio-1-col.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | One Column Portfolio 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active One Column Portfolio 13 | / /.row 14 | / Project One 15 | .row 16 | .col-md-7 17 | = link_to page_path('portfolio-item') do 18 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x300"}/ 19 | .col-md-5 20 | %h3 Project One 21 | %h4 Subheading 22 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium veniam exercitationem expedita laborum at voluptate. Labore, voluptates totam at aut nemo deserunt rem magni pariatur quos perspiciatis atque eveniet unde. 23 | = link_to 'View Project', page_path('portfolio-item'), class: 'btn btn-primary' 24 | / /.row 25 | %hr/ 26 | / Project Two 27 | .row 28 | .col-md-7 29 | = link_to page_path('portfolio-item') do 30 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x300"}/ 31 | .col-md-5 32 | %h3 Project Two 33 | %h4 Subheading 34 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, odit velit cumque vero doloremque repellendus distinctio maiores rem expedita a nam vitae modi quidem similique ducimus! Velit, esse totam tempore. 35 | = link_to 'View Project', page_path('portfolio-item'), class: 'btn btn-primary' 36 | / /.row 37 | %hr/ 38 | / Project Three 39 | .row 40 | .col-md-7 41 | = link_to page_path('portfolio-item') do 42 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x300"}/ 43 | .col-md-5 44 | %h3 Project Three 45 | %h4 Subheading 46 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis, temporibus, dolores, at, praesentium ut unde repudiandae voluptatum sit ab debitis suscipit fugiat natus velit excepturi amet commodi deleniti alias possimus! 47 | = link_to 'View Project', page_path('portfolio-item'), class: 'btn btn-primary' 48 | / /.row 49 | %hr/ 50 | / Project Four 51 | .row 52 | .col-md-7 53 | = link_to page_path('portfolio-item') do 54 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x300"}/ 55 | .col-md-5 56 | %h3 Project Four 57 | %h4 Subheading 58 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo, quidem, consectetur, officia rem officiis illum aliquam perspiciatis aspernatur quod modi hic nemo qui soluta aut eius fugit quam in suscipit? 59 | = link_to 'View Project', page_path('portfolio-item'), class: 'btn btn-primary' 60 | / /.row 61 | %hr/ 62 | / Project Five 63 | .row 64 | .col-md-7 65 | %a{:href => "#"} 66 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x300"}/ 67 | .col-md-5 68 | %h3 Project Five 69 | %h4 Subheading 70 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid, quo, minima, inventore voluptatum saepe quos nostrum provident ex quisquam hic odio repellendus atque porro distinctio quae id laboriosam facilis dolorum. 71 | %a.btn.btn-primary{:href => "#"} View Project 72 | / /.row 73 | %hr/ 74 | / Pagination 75 | .row.text-center 76 | .col-lg-12 77 | %ul.pagination 78 | %li 79 | %a{:href => "#"} « 80 | %li.active 81 | %a{:href => "#"} 1 82 | %li 83 | %a{:href => "#"} 2 84 | %li 85 | %a{:href => "#"} 3 86 | %li 87 | %a{:href => "#"} 4 88 | %li 89 | %a{:href => "#"} 5 90 | %li 91 | %a{:href => "#"} » 92 | / /.row 93 | / /.container 94 | -------------------------------------------------------------------------------- /config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | devise: 5 | confirmations: 6 | confirmed: "Your email address has been successfully confirmed." 7 | send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." 8 | send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." 9 | failure: 10 | already_authenticated: "You are already signed in." 11 | inactive: "Your account is not activated yet." 12 | invalid: "Invalid %{authentication_keys} or password." 13 | locked: "Your account is locked." 14 | last_attempt: "You have one more attempt before your account is locked." 15 | not_found_in_database: "Invalid %{authentication_keys} or password." 16 | timeout: "Your session expired. Please sign in again to continue." 17 | unauthenticated: "You need to sign in or sign up before continuing." 18 | unconfirmed: "You have to confirm your email address before continuing." 19 | mailer: 20 | confirmation_instructions: 21 | subject: "Confirmation instructions" 22 | reset_password_instructions: 23 | subject: "Reset password instructions" 24 | unlock_instructions: 25 | subject: "Unlock instructions" 26 | email_changed: 27 | subject: "Email Changed" 28 | password_change: 29 | subject: "Password Changed" 30 | omniauth_callbacks: 31 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"." 32 | success: "Successfully authenticated from %{kind} account." 33 | passwords: 34 | no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." 35 | send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." 36 | send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." 37 | updated: "Your password has been changed successfully. You are now signed in." 38 | updated_not_active: "Your password has been changed successfully." 39 | registrations: 40 | destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." 41 | signed_up: "Welcome! You have signed up successfully." 42 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." 43 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." 44 | signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." 45 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address." 46 | updated: "Your account has been updated successfully." 47 | sessions: 48 | signed_in: "Signed in successfully." 49 | signed_out: "Signed out successfully." 50 | already_signed_out: "Signed out successfully." 51 | unlocks: 52 | send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." 53 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." 54 | unlocked: "Your account has been unlocked successfully. Please sign in to continue." 55 | errors: 56 | messages: 57 | already_confirmed: "was already confirmed, please try signing in" 58 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" 59 | expired: "has expired, please request a new one" 60 | not_found: "not found" 61 | not_locked: "was not locked" 62 | not_saved: 63 | one: "1 error prohibited this %{resource} from being saved:" 64 | other: "%{count} errors prohibited this %{resource} from being saved:" 65 | -------------------------------------------------------------------------------- /app/views/pages/portfolio-3-col.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Three Column Portfolio 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Three Column Portfolio 13 | / /.row 14 | / Projects Row 15 | .row 16 | .col-md-4.img-portfolio 17 | = link_to page_path('portfolio-item') do 18 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 19 | %h3 20 | = link_to 'Project Name', page_path('portfolio-item') 21 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 22 | .col-md-4.img-portfolio 23 | = link_to page_path('portfolio-item') do 24 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 25 | %h3 26 | = link_to 'Project Name', page_path('portfolio-item') 27 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 28 | .col-md-4.img-portfolio 29 | = link_to page_path('portfolio-item') do 30 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 31 | %h3 32 | = link_to 'Project Name', page_path('portfolio-item') 33 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 34 | / /.row 35 | / Projects Row 36 | .row 37 | .col-md-4.img-portfolio 38 | = link_to page_path('portfolio-item') do 39 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 40 | %h3 41 | = link_to 'Project Name', page_path('portfolio-item') 42 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 43 | .col-md-4.img-portfolio 44 | = link_to page_path('portfolio-item') do 45 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 46 | %h3 47 | = link_to 'Project Name', page_path('portfolio-item') 48 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 49 | .col-md-4.img-portfolio 50 | = link_to page_path('portfolio-item') do 51 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 52 | %h3 53 | = link_to 'Project Name', page_path('portfolio-item') 54 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 55 | / Projects Row 56 | .row 57 | .col-md-4.img-portfolio 58 | = link_to page_path('portfolio-item') do 59 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 60 | %h3 61 | = link_to 'Project Name', page_path('portfolio-item') 62 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 63 | .col-md-4.img-portfolio 64 | = link_to page_path('portfolio-item') do 65 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 66 | %h3 67 | = link_to 'Project Name', page_path('portfolio-item') 68 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 69 | .col-md-4.img-portfolio 70 | = link_to page_path('portfolio-item') do 71 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/700x400"}/ 72 | %h3 73 | = link_to 'Project Name', page_path('portfolio-item') 74 | %p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam viverra euismod odio, gravida pellentesque urna varius vitae. 75 | / /.row 76 | %hr/ 77 | / Pagination 78 | .row.text-center 79 | .col-lg-12 80 | %ul.pagination 81 | %li 82 | %a{:href => "#"} « 83 | %li.active 84 | %a{:href => "#"} 1 85 | %li 86 | %a{:href => "#"} 2 87 | %li 88 | %a{:href => "#"} 3 89 | %li 90 | %a{:href => "#"} 4 91 | %li 92 | %a{:href => "#"} 5 93 | %li 94 | %a{:href => "#"} » 95 | / /.row 96 | / /.container 97 | -------------------------------------------------------------------------------- /app/views/pages/blog-home-1.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Blog Home One 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Blog Home One 13 | / /.row 14 | .row 15 | / Blog Entries Column 16 | .col-md-8 17 | / First Blog Post 18 | %h2 19 | %a{:href => "#"} Blog Post Title 20 | %p.lead 21 | by #{link_to 'Start Bootstrap', root_path} 22 | %p 23 | %i.fa.fa-clock-o 24 | Posted on August 28, 2013 at 10:00 PM 25 | %hr/ 26 | = link_to page_path('blog-post') do 27 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/900x300"}/ 28 | %hr/ 29 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore, veritatis, tempora, necessitatibus inventore nisi quam quia repellat ut tempore laborum possimus eum dicta id animi corrupti debitis ipsum officiis rerum. 30 | = link_to page_path('blog-post'), class: 'btn btn-primary' do 31 | Read More 32 | %i.fa.fa-angle-right 33 | %hr/ 34 | / Second Blog Post 35 | %h2 36 | %a{:href => "#"} Blog Post Title 37 | %p.lead 38 | by #{link_to 'Start Bootstrap', root_path} 39 | %p 40 | %i.fa.fa-clock-o 41 | Posted on August 28, 2013 at 10:45 PM 42 | %hr/ 43 | = link_to page_path('blog-post') do 44 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/900x300"}/ 45 | %hr/ 46 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quibusdam, quasi, fugiat, asperiores harum voluptatum tenetur a possimus nesciunt quod accusamus saepe tempora ipsam distinctio minima dolorum perferendis labore impedit voluptates! 47 | = link_to page_path('blog-post'), class: 'btn btn-primary' do 48 | Read More 49 | %i.fa.fa-angle-right 50 | %hr/ 51 | / Third Blog Post 52 | %h2 53 | %a{:href => "#"} Blog Post Title 54 | %p.lead 55 | by #{link_to 'Start Bootstrap', root_path} 56 | %p 57 | %i.fa.fa-clock-o 58 | Posted on August 28, 2013 at 10:45 PM 59 | %hr/ 60 | = link_to page_path('blog-post') do 61 | %img.img-responsive.img-hover{:alt => "", :src => "http://placehold.it/900x300"}/ 62 | %hr/ 63 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate, voluptates, voluptas dolore ipsam cumque quam veniam accusantium laudantium adipisci architecto itaque dicta aperiam maiores provident id incidunt autem. Magni, ratione. 64 | = link_to page_path('blog-post'), class: 'btn btn-primary' do 65 | Read More 66 | %i.fa.fa-angle-right 67 | %hr/ 68 | / Pager 69 | %ul.pager 70 | %li.previous 71 | %a{:href => "#"} ← Older 72 | %li.next 73 | %a{:href => "#"} Newer → 74 | / Blog Sidebar Widgets Column 75 | .col-md-4 76 | / Blog Search Well 77 | .well 78 | %h4 Blog Search 79 | .input-group 80 | %input.form-control{:type => "text"}/ 81 | %span.input-group-btn 82 | %button.btn.btn-default{:type => "button"} 83 | %i.fa.fa-search 84 | / /.input-group 85 | / Blog Categories Well 86 | .well 87 | %h4 Blog Categories 88 | .row 89 | .col-lg-6 90 | %ul.list-unstyled 91 | %li 92 | %a{:href => "#"} Category Name 93 | %li 94 | %a{:href => "#"} Category Name 95 | %li 96 | %a{:href => "#"} Category Name 97 | %li 98 | %a{:href => "#"} Category Name 99 | / /.col-lg-6 100 | .col-lg-6 101 | %ul.list-unstyled 102 | %li 103 | %a{:href => "#"} Category Name 104 | %li 105 | %a{:href => "#"} Category Name 106 | %li 107 | %a{:href => "#"} Category Name 108 | %li 109 | %a{:href => "#"} Category Name 110 | / /.col-lg-6 111 | / /.row 112 | / Side Widget Well 113 | .well 114 | %h4 Side Widget Well 115 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, perspiciatis adipisci accusamus laudantium odit aliquam repellat tempore quos aspernatur vero. 116 | / /.row 117 | / /.container 118 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.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 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Disable serving static files from the `/public` folder by default since 18 | # Apache or NGINX already handles this. 19 | config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? 20 | 21 | # Compress JavaScripts and CSS. 22 | config.assets.js_compressor = :uglifier 23 | # config.assets.css_compressor = :sass 24 | 25 | # Do not fallback to assets pipeline if a precompiled asset is missed. 26 | config.assets.compile = false 27 | 28 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 29 | 30 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 31 | # config.action_controller.asset_host = 'http://assets.example.com' 32 | 33 | # Specifies the header that your server uses for sending files. 34 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 35 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 36 | 37 | # Mount Action Cable outside main process or domain 38 | # config.action_cable.mount_path = nil 39 | # config.action_cable.url = 'wss://example.com/cable' 40 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] 41 | 42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 43 | # config.force_ssl = true 44 | 45 | # Use the lowest log level to ensure availability of diagnostic information 46 | # when problems arise. 47 | config.log_level = :debug 48 | 49 | # Prepend all log lines with the following tags. 50 | config.log_tags = [ :request_id ] 51 | 52 | # Use a different cache store in production. 53 | # config.cache_store = :mem_cache_store 54 | 55 | # Use a real queuing backend for Active Job (and separate queues per environment) 56 | # config.active_job.queue_adapter = :resque 57 | # config.active_job.queue_name_prefix = "bitparrot_#{Rails.env}" 58 | config.action_mailer.perform_caching = false 59 | 60 | # Ignore bad email addresses and do not raise email delivery errors. 61 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 62 | # config.action_mailer.raise_delivery_errors = false 63 | 64 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 65 | # the I18n.default_locale when a translation cannot be found). 66 | config.i18n.fallbacks = true 67 | 68 | # Send deprecation notices to registered listeners. 69 | config.active_support.deprecation = :notify 70 | 71 | config.action_mailer.smtp_settings = { 72 | address: "smtp.sendgrid.net", 73 | port: 587, 74 | domain: Rails.application.secrets.domain_name, 75 | authentication: "plain", 76 | enable_starttls_auto: true, 77 | user_name: Rails.application.secrets.email_provider_username, 78 | password: Rails.application.secrets.email_provider_password 79 | } 80 | # ActionMailer Config 81 | config.action_mailer.default_url_options = { :host => Rails.application.secrets.domain_name } 82 | config.action_mailer.delivery_method = :smtp 83 | config.action_mailer.perform_deliveries = true 84 | config.action_mailer.raise_delivery_errors = false 85 | 86 | 87 | # Use default logging formatter so that PID and timestamp are not suppressed. 88 | config.log_formatter = ::Logger::Formatter.new 89 | 90 | # Use a different logger for distributed setups. 91 | # require 'syslog/logger' 92 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') 93 | 94 | if ENV["RAILS_LOG_TO_STDOUT"].present? 95 | logger = ActiveSupport::Logger.new(STDOUT) 96 | logger.formatter = config.log_formatter 97 | config.logger = ActiveSupport::TaggedLogging.new(logger) 98 | end 99 | 100 | # Do not dump schema after migrations. 101 | config.active_record.dump_schema_after_migration = false 102 | end 103 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file was generated by the `rails generate rspec:install` command. Conventionally, all 2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 3 | # The generated `.rspec` file contains `--require spec_helper` which will cause 4 | # this file to always be loaded, without a need to explicitly require it in any 5 | # files. 6 | # 7 | # Given that it is always loaded, you are encouraged to keep this file as 8 | # light-weight as possible. Requiring heavyweight dependencies from this file 9 | # will add to the boot time of your test suite on EVERY test run, even for an 10 | # individual file that may not need all of that loaded. Instead, consider making 11 | # a separate helper file that requires the additional dependencies and performs 12 | # the additional setup, and require it from the spec files that actually need 13 | # it. 14 | # 15 | # The `.rspec` file also contains a few flags that are not defaults but that 16 | # users commonly want. 17 | # 18 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 19 | RSpec.configure do |config| 20 | # rspec-expectations config goes here. You can use an alternate 21 | # assertion/expectation library such as wrong or the stdlib/minitest 22 | # assertions if you prefer. 23 | config.expect_with :rspec do |expectations| 24 | # This option will default to `true` in RSpec 4. It makes the `description` 25 | # and `failure_message` of custom matchers include text for helper methods 26 | # defined using `chain`, e.g.: 27 | # be_bigger_than(2).and_smaller_than(4).description 28 | # # => "be bigger than 2 and smaller than 4" 29 | # ...rather than: 30 | # # => "be bigger than 2" 31 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 32 | end 33 | 34 | # rspec-mocks config goes here. You can use an alternate test double 35 | # library (such as bogus or mocha) by changing the `mock_with` option here. 36 | config.mock_with :rspec do |mocks| 37 | # Prevents you from mocking or stubbing a method that does not exist on 38 | # a real object. This is generally recommended, and will default to 39 | # `true` in RSpec 4. 40 | mocks.verify_partial_doubles = true 41 | end 42 | 43 | # This option will default to `:apply_to_host_groups` in RSpec 4 (and will 44 | # have no way to turn it off -- the option exists only for backwards 45 | # compatibility in RSpec 3). It causes shared context metadata to be 46 | # inherited by the metadata hash of host groups and examples, rather than 47 | # triggering implicit auto-inclusion in groups with matching metadata. 48 | config.shared_context_metadata_behavior = :apply_to_host_groups 49 | 50 | # The settings below are suggested to provide a good initial experience 51 | # with RSpec, but feel free to customize to your heart's content. 52 | =begin 53 | # This allows you to limit a spec run to individual examples or groups 54 | # you care about by tagging them with `:focus` metadata. When nothing 55 | # is tagged with `:focus`, all examples get run. RSpec also provides 56 | # aliases for `it`, `describe`, and `context` that include `:focus` 57 | # metadata: `fit`, `fdescribe` and `fcontext`, respectively. 58 | config.filter_run_when_matching :focus 59 | 60 | # Allows RSpec to persist some state between runs in order to support 61 | # the `--only-failures` and `--next-failure` CLI options. We recommend 62 | # you configure your source control system to ignore this file. 63 | config.example_status_persistence_file_path = "spec/examples.txt" 64 | 65 | # Limits the available syntax to the non-monkey patched syntax that is 66 | # recommended. For more details, see: 67 | # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ 68 | # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ 69 | # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode 70 | config.disable_monkey_patching! 71 | 72 | # Many RSpec users commonly either run the entire suite or an individual 73 | # file, and it's useful to allow more verbose output when running an 74 | # individual spec file. 75 | if config.files_to_run.one? 76 | # Use the documentation formatter for detailed output, 77 | # unless a formatter has already been configured 78 | # (e.g. via a command-line flag). 79 | config.default_formatter = 'doc' 80 | end 81 | 82 | # Print the 10 slowest examples and example groups at the 83 | # end of the spec run, to help surface which specs are running 84 | # particularly slow. 85 | config.profile_examples = 10 86 | 87 | # Run specs in random order to surface order dependencies. If you find an 88 | # order dependency and want to debug it, you can fix the order by providing 89 | # the seed, which is printed after each run. 90 | # --seed 1234 91 | config.order = :random 92 | 93 | # Seed global randomization in this process using the `--seed` CLI option. 94 | # Setting this allows you to use `--seed` to deterministically reproduce 95 | # test failures related to randomization by passing the same `--seed` value 96 | # as the one that triggered the failure. 97 | Kernel.srand config.seed 98 | =end 99 | end 100 | -------------------------------------------------------------------------------- /app/views/pages/blog-post.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Blog Post 8 | %small 9 | by 10 | %a{:href => "#"} Start Bootstrap 11 | %ol.breadcrumb 12 | %li 13 | = link_to 'Home', root_path 14 | %li.active Blog Post 15 | / /.row 16 | / Content Row 17 | .row 18 | / Blog Post Content Column 19 | .col-lg-8 20 | / Blog Post 21 | %hr/ 22 | / Date/Time 23 | %p 24 | %i.fa.fa-clock-o 25 | Posted on August 24, 2013 at 9:00 PM 26 | %hr/ 27 | / Preview Image 28 | %img.img-responsive{:alt => "", :src => "http://placehold.it/900x300"}/ 29 | %hr/ 30 | / Post Content 31 | %p.lead Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus, vero, obcaecati, aut, error quam sapiente nemo saepe quibusdam sit excepturi nam quia corporis eligendi eos magni recusandae laborum minus inventore? 32 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, tenetur natus doloremque laborum quos iste ipsum rerum obcaecati impedit odit illo dolorum ab tempora nihil dicta earum fugiat. Temporibus, voluptatibus. 33 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos, doloribus, dolorem iusto blanditiis unde eius illum consequuntur neque dicta incidunt ullam ea hic porro optio ratione repellat perspiciatis. Enim, iure! 34 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error, nostrum, aliquid, animi, ut quas placeat totam sunt tempora commodi nihil ullam alias modi dicta saepe minima ab quo voluptatem obcaecati? 35 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum, dolor quis. Sunt, ut, explicabo, aliquam tenetur ratione tempore quidem voluptates cupiditate voluptas illo saepe quaerat numquam recusandae? Qui, necessitatibus, est! 36 | %hr/ 37 | / Blog Comments 38 | / Comments Form 39 | .well 40 | %h4 Leave a Comment: 41 | %form{:role => "form"} 42 | .form-group 43 | %textarea.form-control{:rows => "3"} 44 | %button.btn.btn-primary{:type => "submit"} Submit 45 | %hr/ 46 | / Posted Comments 47 | / Comment 48 | .media 49 | %a.pull-left{:href => "#"} 50 | %img.media-object{:alt => "", :src => "http://placehold.it/64x64"}/ 51 | .media-body 52 | %h4.media-heading 53 | Start Bootstrap 54 | %small August 25, 2014 at 9:30 PM 55 | Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. 56 | / Comment 57 | .media 58 | %a.pull-left{:href => "#"} 59 | %img.media-object{:alt => "", :src => "http://placehold.it/64x64"}/ 60 | .media-body 61 | %h4.media-heading 62 | Start Bootstrap 63 | %small August 25, 2014 at 9:30 PM 64 | Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. 65 | / Nested Comment 66 | .media 67 | %a.pull-left{:href => "#"} 68 | %img.media-object{:alt => "", :src => "http://placehold.it/64x64"}/ 69 | .media-body 70 | %h4.media-heading 71 | Nested Start Bootstrap 72 | %small August 25, 2014 at 9:30 PM 73 | Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. 74 | / End Nested Comment 75 | / Blog Sidebar Widgets Column 76 | .col-md-4 77 | / Blog Search Well 78 | .well 79 | %h4 Blog Search 80 | .input-group 81 | %input.form-control{:type => "text"}/ 82 | %span.input-group-btn 83 | %button.btn.btn-default{:type => "button"} 84 | %i.fa.fa-search 85 | / /.input-group 86 | / Blog Categories Well 87 | .well 88 | %h4 Blog Categories 89 | .row 90 | .col-lg-6 91 | %ul.list-unstyled 92 | %li 93 | %a{:href => "#"} Category Name 94 | %li 95 | %a{:href => "#"} Category Name 96 | %li 97 | %a{:href => "#"} Category Name 98 | %li 99 | %a{:href => "#"} Category Name 100 | .col-lg-6 101 | %ul.list-unstyled 102 | %li 103 | %a{:href => "#"} Category Name 104 | %li 105 | %a{:href => "#"} Category Name 106 | %li 107 | %a{:href => "#"} Category Name 108 | %li 109 | %a{:href => "#"} Category Name 110 | / /.row 111 | / Side Widget Well 112 | .well 113 | %h4 Side Widget Well 114 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, perspiciatis adipisci accusamus laudantium odit aliquam repellat tempore quos aspernatur vero. 115 | / /.row 116 | / /.container 117 | -------------------------------------------------------------------------------- /config/initializers/simple_form_bootstrap.rb: -------------------------------------------------------------------------------- 1 | # Use this setup block to configure all options available in SimpleForm. 2 | SimpleForm.setup do |config| 3 | config.error_notification_class = 'alert alert-danger' 4 | config.button_class = 'btn btn-default' 5 | config.boolean_label_class = nil 6 | 7 | config.wrappers :vertical_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 8 | b.use :html5 9 | b.use :placeholder 10 | b.optional :maxlength 11 | b.optional :minlength 12 | b.optional :pattern 13 | b.optional :min_max 14 | b.optional :readonly 15 | b.use :label, class: 'control-label' 16 | 17 | b.use :input, class: 'form-control' 18 | b.use :error, wrap_with: { tag: 'span', class: 'help-block' } 19 | b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 20 | end 21 | 22 | config.wrappers :vertical_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 23 | b.use :html5 24 | b.use :placeholder 25 | b.optional :maxlength 26 | b.optional :minlength 27 | b.optional :readonly 28 | b.use :label, class: 'control-label' 29 | 30 | b.use :input 31 | b.use :error, wrap_with: { tag: 'span', class: 'help-block' } 32 | b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 33 | end 34 | 35 | config.wrappers :vertical_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 36 | b.use :html5 37 | b.optional :readonly 38 | 39 | b.wrapper tag: 'div', class: 'checkbox' do |ba| 40 | ba.use :label_input 41 | end 42 | 43 | b.use :error, wrap_with: { tag: 'span', class: 'help-block' } 44 | b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 45 | end 46 | 47 | config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 48 | b.use :html5 49 | b.optional :readonly 50 | b.use :label, class: 'control-label' 51 | b.use :input 52 | b.use :error, wrap_with: { tag: 'span', class: 'help-block' } 53 | b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 54 | end 55 | 56 | config.wrappers :horizontal_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 57 | b.use :html5 58 | b.use :placeholder 59 | b.optional :maxlength 60 | b.optional :minlength 61 | b.optional :pattern 62 | b.optional :min_max 63 | b.optional :readonly 64 | b.use :label, class: 'col-sm-3 control-label' 65 | 66 | b.wrapper tag: 'div', class: 'col-sm-9' do |ba| 67 | ba.use :input, class: 'form-control' 68 | ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } 69 | ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 70 | end 71 | end 72 | 73 | config.wrappers :horizontal_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 74 | b.use :html5 75 | b.use :placeholder 76 | b.optional :maxlength 77 | b.optional :minlength 78 | b.optional :readonly 79 | b.use :label, class: 'col-sm-3 control-label' 80 | 81 | b.wrapper tag: 'div', class: 'col-sm-9' do |ba| 82 | ba.use :input 83 | ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } 84 | ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 85 | end 86 | end 87 | 88 | config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 89 | b.use :html5 90 | b.optional :readonly 91 | 92 | b.wrapper tag: 'div', class: 'col-sm-offset-3 col-sm-9' do |wr| 93 | wr.wrapper tag: 'div', class: 'checkbox' do |ba| 94 | ba.use :label_input 95 | end 96 | 97 | wr.use :error, wrap_with: { tag: 'span', class: 'help-block' } 98 | wr.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 99 | end 100 | end 101 | 102 | config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 103 | b.use :html5 104 | b.optional :readonly 105 | 106 | b.use :label, class: 'col-sm-3 control-label' 107 | 108 | b.wrapper tag: 'div', class: 'col-sm-9' do |ba| 109 | ba.use :input 110 | ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } 111 | ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 112 | end 113 | end 114 | 115 | config.wrappers :inline_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 116 | b.use :html5 117 | b.use :placeholder 118 | b.optional :maxlength 119 | b.optional :minlength 120 | b.optional :pattern 121 | b.optional :min_max 122 | b.optional :readonly 123 | b.use :label, class: 'sr-only' 124 | 125 | b.use :input, class: 'form-control' 126 | b.use :error, wrap_with: { tag: 'span', class: 'help-block' } 127 | b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 128 | end 129 | 130 | config.wrappers :multi_select, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| 131 | b.use :html5 132 | b.optional :readonly 133 | b.use :label, class: 'control-label' 134 | b.wrapper tag: 'div', class: 'form-inline' do |ba| 135 | ba.use :input, class: 'form-control' 136 | ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } 137 | ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 138 | end 139 | end 140 | # Wrappers for forms and inputs using the Bootstrap toolkit. 141 | # Check the Bootstrap docs (http://getbootstrap.com) 142 | # to learn about the different styles for forms and inputs, 143 | # buttons and other elements. 144 | config.default_wrapper = :vertical_form 145 | config.wrapper_mappings = { 146 | check_boxes: :vertical_radio_and_checkboxes, 147 | radio_buttons: :vertical_radio_and_checkboxes, 148 | file: :vertical_file_input, 149 | boolean: :vertical_boolean, 150 | datetime: :multi_select, 151 | date: :multi_select, 152 | time: :multi_select 153 | } 154 | end 155 | -------------------------------------------------------------------------------- /config/initializers/simple_form.rb: -------------------------------------------------------------------------------- 1 | # Use this setup block to configure all options available in SimpleForm. 2 | SimpleForm.setup do |config| 3 | # Wrappers are used by the form builder to generate a 4 | # complete input. You can remove any component from the 5 | # wrapper, change the order or even add your own to the 6 | # stack. The options given below are used to wrap the 7 | # whole input. 8 | config.wrappers :default, class: :input, 9 | hint_class: :field_with_hint, error_class: :field_with_errors do |b| 10 | ## Extensions enabled by default 11 | # Any of these extensions can be disabled for a 12 | # given input by passing: `f.input EXTENSION_NAME => false`. 13 | # You can make any of these extensions optional by 14 | # renaming `b.use` to `b.optional`. 15 | 16 | # Determines whether to use HTML5 (:email, :url, ...) 17 | # and required attributes 18 | b.use :html5 19 | 20 | # Calculates placeholders automatically from I18n 21 | # You can also pass a string as f.input placeholder: "Placeholder" 22 | b.use :placeholder 23 | 24 | ## Optional extensions 25 | # They are disabled unless you pass `f.input EXTENSION_NAME => true` 26 | # to the input. If so, they will retrieve the values from the model 27 | # if any exists. If you want to enable any of those 28 | # extensions by default, you can change `b.optional` to `b.use`. 29 | 30 | # Calculates maxlength from length validations for string inputs 31 | # and/or database column lengths 32 | b.optional :maxlength 33 | 34 | # Calculate minlength from length validations for string inputs 35 | b.optional :minlength 36 | 37 | # Calculates pattern from format validations for string inputs 38 | b.optional :pattern 39 | 40 | # Calculates min and max from length validations for numeric inputs 41 | b.optional :min_max 42 | 43 | # Calculates readonly automatically from readonly attributes 44 | b.optional :readonly 45 | 46 | ## Inputs 47 | b.use :label_input 48 | b.use :hint, wrap_with: { tag: :span, class: :hint } 49 | b.use :error, wrap_with: { tag: :span, class: :error } 50 | 51 | ## full_messages_for 52 | # If you want to display the full error message for the attribute, you can 53 | # use the component :full_error, like: 54 | # 55 | # b.use :full_error, wrap_with: { tag: :span, class: :error } 56 | end 57 | 58 | # The default wrapper to be used by the FormBuilder. 59 | config.default_wrapper = :default 60 | 61 | # Define the way to render check boxes / radio buttons with labels. 62 | # Defaults to :nested for bootstrap config. 63 | # inline: input + label 64 | # nested: label > input 65 | config.boolean_style = :nested 66 | 67 | # Default class for buttons 68 | config.button_class = 'btn' 69 | 70 | # Method used to tidy up errors. Specify any Rails Array method. 71 | # :first lists the first message for each field. 72 | # Use :to_sentence to list all errors for each field. 73 | # config.error_method = :first 74 | 75 | # Default tag used for error notification helper. 76 | config.error_notification_tag = :div 77 | 78 | # CSS class to add for error notification helper. 79 | config.error_notification_class = 'error_notification' 80 | 81 | # ID to add for error notification helper. 82 | # config.error_notification_id = nil 83 | 84 | # Series of attempts to detect a default label method for collection. 85 | # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] 86 | 87 | # Series of attempts to detect a default value method for collection. 88 | # config.collection_value_methods = [ :id, :to_s ] 89 | 90 | # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. 91 | # config.collection_wrapper_tag = nil 92 | 93 | # You can define the class to use on all collection wrappers. Defaulting to none. 94 | # config.collection_wrapper_class = nil 95 | 96 | # You can wrap each item in a collection of radio/check boxes with a tag, 97 | # defaulting to :span. 98 | # config.item_wrapper_tag = :span 99 | 100 | # You can define a class to use in all item wrappers. Defaulting to none. 101 | # config.item_wrapper_class = nil 102 | 103 | # How the label text should be generated altogether with the required text. 104 | # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" } 105 | 106 | # You can define the class to use on all labels. Default is nil. 107 | # config.label_class = nil 108 | 109 | # You can define the default class to be used on forms. Can be overriden 110 | # with `html: { :class }`. Defaulting to none. 111 | # config.default_form_class = nil 112 | 113 | # You can define which elements should obtain additional classes 114 | # config.generate_additional_classes_for = [:wrapper, :label, :input] 115 | 116 | # Whether attributes are required by default (or not). Default is true. 117 | # config.required_by_default = true 118 | 119 | # Tell browsers whether to use the native HTML5 validations (novalidate form option). 120 | # These validations are enabled in SimpleForm's internal config but disabled by default 121 | # in this configuration, which is recommended due to some quirks from different browsers. 122 | # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations, 123 | # change this configuration to true. 124 | config.browser_validations = false 125 | 126 | # Collection of methods to detect if a file type was given. 127 | # config.file_methods = [ :mounted_as, :file?, :public_filename ] 128 | 129 | # Custom mappings for input types. This should be a hash containing a regexp 130 | # to match as key, and the input type that will be used when the field name 131 | # matches the regexp as value. 132 | # config.input_mappings = { /count/ => :integer } 133 | 134 | # Custom wrappers for input types. This should be a hash containing an input 135 | # type as key and the wrapper that will be used for all inputs with specified type. 136 | # config.wrapper_mappings = { string: :prepend } 137 | 138 | # Namespaces where SimpleForm should look for custom input classes that 139 | # override default inputs. 140 | # config.custom_inputs_namespaces << "CustomInputs" 141 | 142 | # Default priority for time_zone inputs. 143 | # config.time_zone_priority = nil 144 | 145 | # Default priority for country inputs. 146 | # config.country_priority = nil 147 | 148 | # When false, do not use translations for labels. 149 | # config.translate_labels = true 150 | 151 | # Automatically discover new inputs in Rails' autoload path. 152 | # config.inputs_discovery = true 153 | 154 | # Cache SimpleForm inputs discovery 155 | # config.cache_discovery = !Rails.env.development? 156 | 157 | # Default class for inputs 158 | # config.input_class = nil 159 | 160 | # Define the default class of the input wrapper of the boolean input. 161 | config.boolean_label_class = 'checkbox' 162 | 163 | # Defines if the default input wrapper class should be included in radio 164 | # collection wrappers. 165 | # config.include_default_input_wrapper_class = true 166 | 167 | # Defines which i18n scope will be used in Simple Form. 168 | # config.i18n_scope = 'simple_form' 169 | end 170 | -------------------------------------------------------------------------------- /app/assets/images/favicon/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 126 | 128 | 129 | 130 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actioncable (5.0.2) 5 | actionpack (= 5.0.2) 6 | nio4r (>= 1.2, < 3.0) 7 | websocket-driver (~> 0.6.1) 8 | actionmailer (5.0.2) 9 | actionpack (= 5.0.2) 10 | actionview (= 5.0.2) 11 | activejob (= 5.0.2) 12 | mail (~> 2.5, >= 2.5.4) 13 | rails-dom-testing (~> 2.0) 14 | actionpack (5.0.2) 15 | actionview (= 5.0.2) 16 | activesupport (= 5.0.2) 17 | rack (~> 2.0) 18 | rack-test (~> 0.6.3) 19 | rails-dom-testing (~> 2.0) 20 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 21 | actionview (5.0.2) 22 | activesupport (= 5.0.2) 23 | builder (~> 3.1) 24 | erubis (~> 2.7.0) 25 | rails-dom-testing (~> 2.0) 26 | rails-html-sanitizer (~> 1.0, >= 1.0.3) 27 | activejob (5.0.2) 28 | activesupport (= 5.0.2) 29 | globalid (>= 0.3.6) 30 | activemodel (5.0.2) 31 | activesupport (= 5.0.2) 32 | activerecord (5.0.2) 33 | activemodel (= 5.0.2) 34 | activesupport (= 5.0.2) 35 | arel (~> 7.0) 36 | activesupport (5.0.2) 37 | concurrent-ruby (~> 1.0, >= 1.0.2) 38 | i18n (~> 0.7) 39 | minitest (~> 5.1) 40 | tzinfo (~> 1.1) 41 | addressable (2.5.0) 42 | public_suffix (~> 2.0, >= 2.0.2) 43 | arel (7.1.4) 44 | autoprefixer-rails (6.7.7.1) 45 | execjs 46 | bcrypt (3.1.11) 47 | better_errors (2.1.1) 48 | coderay (>= 1.0.0) 49 | erubis (>= 2.6.6) 50 | rack (>= 0.9.0) 51 | bootstrap-sass (3.3.7) 52 | autoprefixer-rails (>= 5.2.1) 53 | sass (>= 3.3.4) 54 | buftok (0.2.0) 55 | builder (3.2.3) 56 | byebug (9.0.6) 57 | capybara (2.13.0) 58 | addressable 59 | mime-types (>= 1.16) 60 | nokogiri (>= 1.3.3) 61 | rack (>= 1.0.0) 62 | rack-test (>= 0.5.4) 63 | xpath (~> 2.0) 64 | childprocess (0.6.2) 65 | ffi (~> 1.0, >= 1.0.11) 66 | coderay (1.1.1) 67 | coffee-rails (4.2.1) 68 | coffee-script (>= 2.2.0) 69 | railties (>= 4.0.0, < 5.2.x) 70 | coffee-script (2.4.1) 71 | coffee-script-source 72 | execjs 73 | coffee-script-source (1.12.2) 74 | concurrent-ruby (1.0.5) 75 | database_cleaner (1.5.3) 76 | debug_inspector (0.0.2) 77 | devise (4.2.1) 78 | bcrypt (~> 3.0) 79 | orm_adapter (~> 0.1) 80 | railties (>= 4.1.0, < 5.1) 81 | responders 82 | warden (~> 1.2.3) 83 | devise_invitable (1.7.1) 84 | actionmailer (>= 4.1.0) 85 | devise (>= 4.0.0) 86 | diff-lcs (1.3) 87 | domain_name (0.5.20170223) 88 | unf (>= 0.0.5, < 1.0.0) 89 | equalizer (0.0.11) 90 | erubis (2.7.0) 91 | execjs (2.7.0) 92 | factory_girl (4.8.0) 93 | activesupport (>= 3.0.0) 94 | factory_girl_rails (4.8.0) 95 | factory_girl (~> 4.8.0) 96 | railties (>= 3.0.0) 97 | faker (1.7.3) 98 | i18n (~> 0.5) 99 | faraday (0.11.0) 100 | multipart-post (>= 1.2, < 3) 101 | ffi (1.9.18) 102 | figaro (1.1.1) 103 | thor (~> 0.14) 104 | globalid (0.3.7) 105 | activesupport (>= 4.1.0) 106 | haml (4.0.7) 107 | tilt 108 | haml-rails (0.9.0) 109 | actionpack (>= 4.0.1) 110 | activesupport (>= 4.0.1) 111 | haml (>= 4.0.6, < 5.0) 112 | html2haml (>= 1.0.1) 113 | railties (>= 4.0.1) 114 | high_voltage (3.0.0) 115 | html2haml (2.1.0) 116 | erubis (~> 2.7.0) 117 | haml (~> 4.0) 118 | nokogiri (>= 1.6.0) 119 | ruby_parser (~> 3.5) 120 | http (2.2.1) 121 | addressable (~> 2.3) 122 | http-cookie (~> 1.0) 123 | http-form_data (~> 1.0.1) 124 | http_parser.rb (~> 0.6.0) 125 | http-cookie (1.0.3) 126 | domain_name (~> 0.5) 127 | http-form_data (1.0.1) 128 | http_parser.rb (0.6.0) 129 | httparty (0.14.0) 130 | multi_xml (>= 0.5.2) 131 | i18n (0.8.1) 132 | jbuilder (2.6.3) 133 | activesupport (>= 3.0.0, < 5.2) 134 | multi_json (~> 1.2) 135 | jquery-rails (4.3.1) 136 | rails-dom-testing (>= 1, < 3) 137 | railties (>= 4.2.0) 138 | thor (>= 0.14, < 2.0) 139 | json (2.1.0) 140 | launchy (2.4.3) 141 | addressable (~> 2.3) 142 | letter_opener (1.4.1) 143 | launchy (~> 2.2) 144 | listen (3.0.8) 145 | rb-fsevent (~> 0.9, >= 0.9.4) 146 | rb-inotify (~> 0.9, >= 0.9.7) 147 | loofah (2.0.3) 148 | nokogiri (>= 1.5.9) 149 | mail (2.6.4) 150 | mime-types (>= 1.16, < 4) 151 | memoizable (0.4.2) 152 | thread_safe (~> 0.3, >= 0.3.1) 153 | method_source (0.8.2) 154 | mime-types (3.1) 155 | mime-types-data (~> 3.2015) 156 | mime-types-data (3.2016.0521) 157 | mini_portile2 (2.1.0) 158 | minitest (5.10.1) 159 | multi_json (1.12.1) 160 | multi_xml (0.6.0) 161 | multipart-post (2.0.0) 162 | naught (1.1.0) 163 | netrc (0.11.0) 164 | nio4r (2.0.0) 165 | nokogiri (1.7.1) 166 | mini_portile2 (~> 2.1.0) 167 | orm_adapter (0.5.0) 168 | pg (0.20.0) 169 | public_suffix (2.0.5) 170 | puma (3.8.2) 171 | pundit (1.1.0) 172 | activesupport (>= 3.0.0) 173 | rack (2.0.1) 174 | rack-test (0.6.3) 175 | rack (>= 1.0) 176 | rails (5.0.2) 177 | actioncable (= 5.0.2) 178 | actionmailer (= 5.0.2) 179 | actionpack (= 5.0.2) 180 | actionview (= 5.0.2) 181 | activejob (= 5.0.2) 182 | activemodel (= 5.0.2) 183 | activerecord (= 5.0.2) 184 | activesupport (= 5.0.2) 185 | bundler (>= 1.3.0, < 2.0) 186 | railties (= 5.0.2) 187 | sprockets-rails (>= 2.0.0) 188 | rails-dom-testing (2.0.2) 189 | activesupport (>= 4.2.0, < 6.0) 190 | nokogiri (~> 1.6) 191 | rails-html-sanitizer (1.0.3) 192 | loofah (~> 2.0) 193 | rails_layout (1.0.34) 194 | rails_real_favicon (0.0.7) 195 | json (>= 1.7, < 3) 196 | rails (>= 3.1) 197 | rest-client (~> 2.0) 198 | rubyzip (~> 1) 199 | railties (5.0.2) 200 | actionpack (= 5.0.2) 201 | activesupport (= 5.0.2) 202 | method_source 203 | rake (>= 0.8.7) 204 | thor (>= 0.18.1, < 2.0) 205 | rake (12.0.0) 206 | rb-fsevent (0.9.8) 207 | rb-inotify (0.9.8) 208 | ffi (>= 0.5.0) 209 | responders (2.3.0) 210 | railties (>= 4.2.0, < 5.1) 211 | rest-client (2.0.2) 212 | http-cookie (>= 1.0.2, < 2.0) 213 | mime-types (>= 1.16, < 4.0) 214 | netrc (~> 0.8) 215 | rspec-core (3.5.4) 216 | rspec-support (~> 3.5.0) 217 | rspec-expectations (3.5.0) 218 | diff-lcs (>= 1.2.0, < 2.0) 219 | rspec-support (~> 3.5.0) 220 | rspec-mocks (3.5.0) 221 | diff-lcs (>= 1.2.0, < 2.0) 222 | rspec-support (~> 3.5.0) 223 | rspec-rails (3.5.2) 224 | actionpack (>= 3.0) 225 | activesupport (>= 3.0) 226 | railties (>= 3.0) 227 | rspec-core (~> 3.5.0) 228 | rspec-expectations (~> 3.5.0) 229 | rspec-mocks (~> 3.5.0) 230 | rspec-support (~> 3.5.0) 231 | rspec-support (3.5.0) 232 | ruby_parser (3.8.4) 233 | sexp_processor (~> 4.1) 234 | rubyzip (1.2.1) 235 | sass (3.4.23) 236 | sass-rails (5.0.6) 237 | railties (>= 4.0.0, < 6) 238 | sass (~> 3.1) 239 | sprockets (>= 2.8, < 4.0) 240 | sprockets-rails (>= 2.0, < 4.0) 241 | tilt (>= 1.1, < 3) 242 | selenium-webdriver (3.3.0) 243 | childprocess (~> 0.5) 244 | rubyzip (~> 1.0) 245 | websocket (~> 1.0) 246 | sexp_processor (4.8.0) 247 | simple_form (3.4.0) 248 | actionpack (> 4, < 5.1) 249 | activemodel (> 4, < 5.1) 250 | simple_oauth (0.3.1) 251 | spring (2.0.1) 252 | activesupport (>= 4.2) 253 | spring-commands-rspec (1.0.4) 254 | spring (>= 0.9.1) 255 | spring-watcher-listen (2.0.1) 256 | listen (>= 2.7, < 4.0) 257 | spring (>= 1.2, < 3.0) 258 | sprockets (3.7.1) 259 | concurrent-ruby (~> 1.0) 260 | rack (> 1, < 3) 261 | sprockets-rails (3.2.0) 262 | actionpack (>= 4.0) 263 | activesupport (>= 4.0) 264 | sprockets (>= 3.0.0) 265 | thor (0.19.4) 266 | thread_safe (0.3.6) 267 | tilt (2.0.7) 268 | turbolinks (5.0.1) 269 | turbolinks-source (~> 5) 270 | turbolinks-source (5.0.0) 271 | twitter (6.1.0) 272 | addressable (~> 2.5) 273 | buftok (~> 0.2.0) 274 | equalizer (= 0.0.11) 275 | faraday (~> 0.11.0) 276 | http (~> 2.1) 277 | http_parser.rb (~> 0.6.0) 278 | memoizable (~> 0.4.2) 279 | naught (~> 1.1) 280 | simple_oauth (~> 0.3.1) 281 | tzinfo (1.2.2) 282 | thread_safe (~> 0.1) 283 | uglifier (3.1.9) 284 | execjs (>= 0.3.0, < 3) 285 | unf (0.1.4) 286 | unf_ext 287 | unf_ext (0.0.7.2) 288 | warden (1.2.7) 289 | rack (>= 1.0) 290 | web-console (3.4.0) 291 | actionview (>= 5.0) 292 | activemodel (>= 5.0) 293 | debug_inspector 294 | railties (>= 5.0) 295 | websocket (1.2.4) 296 | websocket-driver (0.6.5) 297 | websocket-extensions (>= 0.1.0) 298 | websocket-extensions (0.1.2) 299 | xpath (2.0.0) 300 | nokogiri (~> 1.3) 301 | 302 | PLATFORMS 303 | ruby 304 | 305 | DEPENDENCIES 306 | better_errors 307 | bootstrap-sass 308 | byebug 309 | capybara 310 | coffee-rails (~> 4.2) 311 | database_cleaner 312 | devise 313 | devise_invitable 314 | factory_girl_rails 315 | faker 316 | figaro 317 | haml-rails 318 | high_voltage 319 | html2haml 320 | httparty 321 | jbuilder (~> 2.5) 322 | jquery-rails 323 | launchy 324 | letter_opener 325 | listen (~> 3.0.5) 326 | pg 327 | puma (~> 3.0) 328 | pundit 329 | rails (~> 5.0.2) 330 | rails_layout 331 | rails_real_favicon 332 | rspec-rails 333 | sass-rails (~> 5.0) 334 | selenium-webdriver 335 | simple_form 336 | spring 337 | spring-commands-rspec 338 | spring-watcher-listen (~> 2.0.0) 339 | turbolinks (~> 5) 340 | twitter 341 | tzinfo-data 342 | uglifier (>= 1.3.0) 343 | web-console (>= 3.3.0) 344 | 345 | RUBY VERSION 346 | ruby 2.3.1p112 347 | 348 | BUNDLED WITH 349 | 1.14.6 350 | -------------------------------------------------------------------------------- /app/views/pages/services.html.haml: -------------------------------------------------------------------------------- 1 | / Page Content 2 | .container 3 | / Page Heading/Breadcrumbs 4 | .row 5 | .col-lg-12 6 | %h1.page-header 7 | Services 8 | %small Subheading 9 | %ol.breadcrumb 10 | %li 11 | = link_to 'Home', root_path 12 | %li.active Services 13 | / /.row 14 | / Image Header 15 | .row 16 | .col-lg-12 17 | %img.img-responsive{:alt => "", :src => "http://placehold.it/1200x300"}/ 18 | / /.row 19 | / Service Panels 20 | / The circle icons use Font Awesome's stacked icon classes. For more information, visit http://fontawesome.io/examples/ 21 | .row 22 | .col-lg-12 23 | %h2.page-header Services Panels 24 | .col-md-3.col-sm-6 25 | .panel.panel-default.text-center 26 | .panel-heading 27 | %span.fa-stack.fa-5x 28 | %i.fa.fa-circle.fa-stack-2x.text-primary 29 | %i.fa.fa-tree.fa-stack-1x.fa-inverse 30 | .panel-body 31 | %h4 Service One 32 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. 33 | %a.btn.btn-primary{:href => "#"} Learn More 34 | .col-md-3.col-sm-6 35 | .panel.panel-default.text-center 36 | .panel-heading 37 | %span.fa-stack.fa-5x 38 | %i.fa.fa-circle.fa-stack-2x.text-primary 39 | %i.fa.fa-car.fa-stack-1x.fa-inverse 40 | .panel-body 41 | %h4 Service Two 42 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. 43 | %a.btn.btn-primary{:href => "#"} Learn More 44 | .col-md-3.col-sm-6 45 | .panel.panel-default.text-center 46 | .panel-heading 47 | %span.fa-stack.fa-5x 48 | %i.fa.fa-circle.fa-stack-2x.text-primary 49 | %i.fa.fa-support.fa-stack-1x.fa-inverse 50 | .panel-body 51 | %h4 Service Three 52 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. 53 | %a.btn.btn-primary{:href => "#"} Learn More 54 | .col-md-3.col-sm-6 55 | .panel.panel-default.text-center 56 | .panel-heading 57 | %span.fa-stack.fa-5x 58 | %i.fa.fa-circle.fa-stack-2x.text-primary 59 | %i.fa.fa-database.fa-stack-1x.fa-inverse 60 | .panel-body 61 | %h4 Service Four 62 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. 63 | %a.btn.btn-primary{:href => "#"} Learn More 64 | / Service Tabs 65 | .row 66 | .col-lg-12 67 | %h2.page-header Service Tabs 68 | .col-lg-12 69 | %ul#myTab.nav.nav-tabs.nav-justified 70 | %li.active 71 | %a{"data-toggle" => "tab", :href => "#service-one"} 72 | %i.fa.fa-tree 73 | Service One 74 | %li 75 | %a{"data-toggle" => "tab", :href => "#service-two"} 76 | %i.fa.fa-car 77 | Service Two 78 | %li 79 | %a{"data-toggle" => "tab", :href => "#service-three"} 80 | %i.fa.fa-support 81 | Service Three 82 | %li 83 | %a{"data-toggle" => "tab", :href => "#service-four"} 84 | %i.fa.fa-database 85 | Service Four 86 | #myTabContent.tab-content 87 | #service-one.tab-pane.fade.active.in 88 | %h4 Service One 89 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 90 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 91 | #service-two.tab-pane.fade 92 | %h4 Service Two 93 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 94 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 95 | #service-three.tab-pane.fade 96 | %h4 Service Three 97 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 98 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 99 | #service-four.tab-pane.fade 100 | %h4 Service Four 101 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 102 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae repudiandae fugiat illo cupiditate excepturi esse officiis consectetur, laudantium qui voluptatem. Ad necessitatibus velit, accusantium expedita debitis impedit rerum totam id. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Natus quibusdam recusandae illum, nesciunt, architecto, saepe facere, voluptas eum incidunt dolores magni itaque autem neque velit in. At quia quaerat asperiores. 103 | / Service List 104 | / The circle icons use Font Awesome's stacked icon classes. For more information, visit http://fontawesome.io/examples/ 105 | .row 106 | .col-lg-12 107 | %h2.page-header Service List 108 | .col-md-4 109 | .media 110 | .pull-left 111 | %span.fa-stack.fa-2x 112 | %i.fa.fa-circle.fa-stack-2x.text-primary 113 | %i.fa.fa-tree.fa-stack-1x.fa-inverse 114 | .media-body 115 | %h4.media-heading Service One 116 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 117 | .media 118 | .pull-left 119 | %span.fa-stack.fa-2x 120 | %i.fa.fa-circle.fa-stack-2x.text-primary 121 | %i.fa.fa-car.fa-stack-1x.fa-inverse 122 | .media-body 123 | %h4.media-heading Service Two 124 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 125 | .media 126 | .pull-left 127 | %span.fa-stack.fa-2x 128 | %i.fa.fa-circle.fa-stack-2x.text-primary 129 | %i.fa.fa-support.fa-stack-1x.fa-inverse 130 | .media-body 131 | %h4.media-heading Service Three 132 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 133 | .col-md-4 134 | .media 135 | .pull-left 136 | %span.fa-stack.fa-2x 137 | %i.fa.fa-circle.fa-stack-2x.text-primary 138 | %i.fa.fa-database.fa-stack-1x.fa-inverse 139 | .media-body 140 | %h4.media-heading Service Four 141 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 142 | .media 143 | .pull-left 144 | %span.fa-stack.fa-2x 145 | %i.fa.fa-circle.fa-stack-2x.text-primary 146 | %i.fa.fa-bomb.fa-stack-1x.fa-inverse 147 | .media-body 148 | %h4.media-heading Service Five 149 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 150 | .media 151 | .pull-left 152 | %span.fa-stack.fa-2x 153 | %i.fa.fa-circle.fa-stack-2x.text-primary 154 | %i.fa.fa-bank.fa-stack-1x.fa-inverse 155 | .media-body 156 | %h4.media-heading Service Six 157 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 158 | .col-md-4 159 | .media 160 | .pull-left 161 | %span.fa-stack.fa-2x 162 | %i.fa.fa-circle.fa-stack-2x.text-primary 163 | %i.fa.fa-paper-plane.fa-stack-1x.fa-inverse 164 | .media-body 165 | %h4.media-heading Service Seven 166 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 167 | .media 168 | .pull-left 169 | %span.fa-stack.fa-2x 170 | %i.fa.fa-circle.fa-stack-2x.text-primary 171 | %i.fa.fa-space-shuttle.fa-stack-1x.fa-inverse 172 | .media-body 173 | %h4.media-heading Service Eight 174 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 175 | .media 176 | .pull-left 177 | %span.fa-stack.fa-2x 178 | %i.fa.fa-circle.fa-stack-2x.text-primary 179 | %i.fa.fa-recycle.fa-stack-1x.fa-inverse 180 | .media-body 181 | %h4.media-heading Service Nine 182 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo itaque ipsum sit harum. 183 | / /.row 184 | / /.container 185 | --------------------------------------------------------------------------------