diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..f0318f016 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore the default SQLite database. +/db/*.sqlite3 +/db/*.sqlite3-journal + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore Byebug command history file. +.byebug_history + + +# Ignore application configuration +*application.yml diff --git a/.rspec b/.rspec new file mode 100644 index 000000000..83e16f804 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..f65146e07 --- /dev/null +++ b/Gemfile @@ -0,0 +1,73 @@ +source 'https://rubygems.org' + + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '~> 5.0.0' +# Use sqlite3 as the database for Active Record +gem 'pg' +# Use Puma as the app server +gem 'puma', '~> 3.0' +# Use SCSS for stylesheets +gem 'sass-rails', '~> 5.0' +# Use Uglifier as compressor for JavaScript assets +gem 'uglifier', '>= 1.3.0' +# Use CoffeeScript for .coffee assets and views +gem 'coffee-rails', '~> 4.2' +# See https://github.com/rails/execjs#readme for more supported runtimes +# gem 'therubyracer', platforms: :ruby +gem 'rails_12factor' +gem 'simple_form' +gem 'validates_timeliness', '~> 4.0' +gem 'aws-sdk' +gem 'paperclip' +gem 'figaro' + +gem 'delayed_job_active_record' + + +# Use jquery as the JavaScript library +gem 'jquery-rails' +# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +gem 'jbuilder', '~> 2.5' +# Use Redis adapter to run Action Cable in production +# gem 'redis', '~> 3.0' +# Use ActiveModel has_secure_password +gem 'bcrypt', '~> 3.1.7' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +group :test do + gem 'shoulda-matchers', '~> 3.1' + gem 'capybara' + gem 'launchy' + gem 'rails-controller-testing' + gem 'pry' +end + +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug', platform: :mri + gem 'better_errors' + gem 'rspec-rails' + gem 'factory_girl_rails', '~> 4.0' + gem 'letter_opener' +end + +gem 'faker' +gem 'binding_of_caller' +gem 'hirb' + +group :development do + # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. + gem 'web-console' + gem 'listen', '~> 3.0.5' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' + gem 'spring-watcher-listen', '~> 2.0.0' + gem 'guard-rspec', require: false +end + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..65480d935 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,312 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.0.0) + actionpack (= 5.0.0) + nio4r (~> 1.2) + websocket-driver (~> 0.6.1) + actionmailer (5.0.0) + actionpack (= 5.0.0) + actionview (= 5.0.0) + activejob (= 5.0.0) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.0.0) + actionview (= 5.0.0) + activesupport (= 5.0.0) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.0.0) + activesupport (= 5.0.0) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + activejob (5.0.0) + activesupport (= 5.0.0) + globalid (>= 0.3.6) + activemodel (5.0.0) + activesupport (= 5.0.0) + activerecord (5.0.0) + activemodel (= 5.0.0) + activesupport (= 5.0.0) + arel (~> 7.0) + activesupport (5.0.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + addressable (2.4.0) + arel (7.1.1) + aws-sdk (2.5.4) + aws-sdk-resources (= 2.5.4) + aws-sdk-core (2.5.4) + jmespath (~> 1.0) + aws-sdk-resources (2.5.4) + aws-sdk-core (= 2.5.4) + bcrypt (3.1.11) + better_errors (2.1.1) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + rack (>= 0.9.0) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + builder (3.2.2) + byebug (9.0.5) + capybara (2.7.1) + addressable + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + climate_control (0.0.3) + activesupport (>= 3.0) + cocaine (0.5.8) + climate_control (>= 0.0.3, < 1.0) + coderay (1.1.1) + coffee-rails (4.2.1) + coffee-script (>= 2.2.0) + railties (>= 4.0.0, < 5.2.x) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.10.0) + concurrent-ruby (1.0.2) + debug_inspector (0.0.2) + delayed_job (4.1.2) + activesupport (>= 3.0, < 5.1) + delayed_job_active_record (4.1.1) + activerecord (>= 3.0, < 5.1) + delayed_job (>= 3.0, < 5) + diff-lcs (1.2.5) + erubis (2.7.0) + execjs (2.7.0) + factory_girl (4.7.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.7.0) + factory_girl (~> 4.7.0) + railties (>= 3.0.0) + faker (1.6.6) + i18n (~> 0.5) + ffi (1.9.14) + figaro (1.1.1) + thor (~> 0.14) + formatador (0.2.5) + globalid (0.3.7) + activesupport (>= 4.1.0) + guard (2.14.0) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (~> 1.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-compat (1.2.1) + guard-rspec (4.7.3) + guard (~> 2.1) + guard-compat (~> 1.1) + rspec (>= 2.99.0, < 4.0) + hirb (0.7.3) + i18n (0.7.0) + jbuilder (2.6.0) + activesupport (>= 3.0.0, < 5.1) + multi_json (~> 1.2) + jmespath (1.3.1) + jquery-rails (4.1.1) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) + launchy (2.4.3) + addressable (~> 2.3) + letter_opener (1.4.1) + launchy (~> 2.2) + listen (3.0.8) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + loofah (2.0.3) + nokogiri (>= 1.5.9) + lumberjack (1.0.10) + mail (2.6.4) + mime-types (>= 1.16, < 4) + method_source (0.8.2) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mimemagic (0.3.2) + mini_portile2 (2.1.0) + minitest (5.9.0) + multi_json (1.12.1) + nenv (0.3.0) + nio4r (1.2.1) + nokogiri (1.6.8) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) + notiffany (0.1.1) + nenv (~> 0.1) + shellany (~> 0.0) + paperclip (5.0.0) + activemodel (>= 4.2.0) + activesupport (>= 4.2.0) + cocaine (~> 0.5.5) + mime-types + mimemagic (~> 0.3.0) + pg (0.18.4) + pkg-config (1.1.7) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + puma (3.6.0) + rack (2.0.1) + rack-test (0.6.3) + rack (>= 1.0) + rails (5.0.0) + actioncable (= 5.0.0) + actionmailer (= 5.0.0) + actionpack (= 5.0.0) + actionview (= 5.0.0) + activejob (= 5.0.0) + activemodel (= 5.0.0) + activerecord (= 5.0.0) + activesupport (= 5.0.0) + bundler (>= 1.3.0, < 2.0) + railties (= 5.0.0) + sprockets-rails (>= 2.0.0) + rails-controller-testing (1.0.1) + actionpack (~> 5.x) + actionview (~> 5.x) + activesupport (~> 5.x) + rails-dom-testing (2.0.1) + activesupport (>= 4.2.0, < 6.0) + nokogiri (~> 1.6.0) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.5) + railties (5.0.0) + actionpack (= 5.0.0) + activesupport (= 5.0.0) + method_source + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (11.2.2) + rb-fsevent (0.9.7) + rb-inotify (0.9.7) + ffi (>= 0.5.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.2) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-rails (3.5.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + sass (3.4.22) + sass-rails (5.0.6) + railties (>= 4.0.0, < 6) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) + shellany (0.0.1) + shoulda-matchers (3.1.1) + activesupport (>= 4.0.0) + simple_form (3.2.1) + actionpack (> 4, < 5.1) + activemodel (> 4, < 5.1) + slop (3.6.0) + spring (1.7.2) + spring-watcher-listen (2.0.0) + listen (>= 2.7, < 4.0) + spring (~> 1.2) + sprockets (3.7.0) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.1.1) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.19.1) + thread_safe (0.3.5) + tilt (2.0.5) + timeliness (0.3.8) + tzinfo (1.2.2) + thread_safe (~> 0.1) + uglifier (3.0.1) + execjs (>= 0.3.0, < 3) + validates_timeliness (4.0.2) + timeliness (~> 0.3.7) + web-console (3.3.1) + actionview (>= 5.0) + activemodel (>= 5.0) + debug_inspector + railties (>= 5.0) + websocket-driver (0.6.4) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.2) + xpath (2.0.0) + nokogiri (~> 1.3) + +PLATFORMS + ruby + +DEPENDENCIES + aws-sdk + bcrypt (~> 3.1.7) + better_errors + binding_of_caller + byebug + capybara + coffee-rails (~> 4.2) + delayed_job_active_record + factory_girl_rails (~> 4.0) + faker + figaro + guard-rspec + hirb + jbuilder (~> 2.5) + jquery-rails + launchy + letter_opener + listen (~> 3.0.5) + paperclip + pg + pry + puma (~> 3.0) + rails (~> 5.0.0) + rails-controller-testing + rails_12factor + rspec-rails + sass-rails (~> 5.0) + shoulda-matchers (~> 3.1) + simple_form + spring + spring-watcher-listen (~> 2.0.0) + tzinfo-data + uglifier (>= 1.3.0) + validates_timeliness (~> 4.0) + web-console + +BUNDLED WITH + 1.12.5 diff --git a/Guardfile b/Guardfile new file mode 100644 index 000000000..3215f0137 --- /dev/null +++ b/Guardfile @@ -0,0 +1,70 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +## Uncomment and set this to only include directories you want to watch +# directories %w(app lib config test spec features) \ +# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")} + +## Note: if you are using the `directories` clause above and you are not +## watching the project directory ('.'), then you will want to move +## the Guardfile to a watched dir and symlink it back, e.g. +# +# $ mkdir config +# $ mv Guardfile config/ +# $ ln -s config/Guardfile . +# +# and, you'll have to watch "config/Guardfile" instead of "Guardfile" + +# Note: The cmd option is now required due to the increasing number of ways +# rspec may be run, below are examples of the most common uses. +# * bundler: 'bundle exec rspec' +# * bundler binstubs: 'bin/rspec' +# * spring: 'bin/rspec' (This will use spring if running and you have +# installed the spring binstubs per the docs) +# * zeus: 'zeus rspec' (requires the server to be started separately) +# * 'just' rspec: 'rspec' + +guard :rspec, cmd: "bundle exec rspec" do + require "guard/rspec/dsl" + dsl = Guard::RSpec::Dsl.new(self) + + # Feel free to open issues for suggestions and improvements + + # RSpec files + rspec = dsl.rspec + watch(rspec.spec_helper) { rspec.spec_dir } + watch(rspec.spec_support) { rspec.spec_dir } + watch(rspec.spec_files) + + # Ruby files + ruby = dsl.ruby + dsl.watch_spec_files_for(ruby.lib_files) + + # Rails files + rails = dsl.rails(view_extensions: %w(erb haml slim)) + dsl.watch_spec_files_for(rails.app_files) + dsl.watch_spec_files_for(rails.views) + + watch(rails.controllers) do |m| + [ + rspec.spec.call("routing/#{m[1]}_routing"), + rspec.spec.call("controllers/#{m[1]}_controller"), + rspec.spec.call("acceptance/#{m[1]}") + ] + end + + # Rails config changes + watch(rails.spec_helper) { rspec.spec_dir } + watch(rails.routes) { "#{rspec.spec_dir}/routing" } + watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" } + + # Capybara features specs + watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") } + watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") } + + # Turnip features and steps + watch(%r{^spec/acceptance/(.+)\.feature$}) + watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m| + Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance" + end +end diff --git a/README.md b/README.md index 24602872a..727921d7c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,13 @@ -danebook -======== +##Alex Lach's Danebook -This is the Real Dane Deal. +"Danebook" is a Facebook-like social network site built during Viking Code School. The live application is available [here](https://lach-danebook.herokuapp.com/)! + +The app allows users to friend other users, write posts, upload photos, and comment and like on their own and others' content. The app was a chance to learn a number of different Rails functionalities, including: + + - polymorphic relationships + - email notifications with Sendgrid + - nested forms + - Paperclip + - AWS + +To get started, you can make your own account or you can log in with email: alex@alex.com and password: password. diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..e85f91391 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative 'config/application' + +Rails.application.load_tasks diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 000000000..b16e53d6d --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1,3 @@ +//= link_tree ../images +//= link_directory ../javascripts .js +//= link_directory ../stylesheets .css diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/assets/images/cover_photo.jpg b/app/assets/images/cover_photo.jpg new file mode 100644 index 000000000..7db69ae78 Binary files /dev/null and b/app/assets/images/cover_photo.jpg differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 000000000..71a5afb74 --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,16 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. JavaScript code in this file should be added after the last require_* statement. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require jquery +//= require jquery_ujs + +//= require_tree . diff --git a/app/assets/javascripts/cable.js b/app/assets/javascripts/cable.js new file mode 100644 index 000000000..71ee1e66d --- /dev/null +++ b/app/assets/javascripts/cable.js @@ -0,0 +1,13 @@ +// Action Cable provides the framework to deal with WebSockets in Rails. +// You can generate new channels where WebSocket features live using the rails generate channel command. +// +//= require action_cable +//= require_self +//= require_tree ./channels + +(function() { + this.App || (this.App = {}); + + App.cable = ActionCable.createConsumer(); + +}).call(this); diff --git a/app/assets/javascripts/channels/.keep b/app/assets/javascripts/channels/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/assets/javascripts/comments.coffee b/app/assets/javascripts/comments.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/comments.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/commentsScript.js b/app/assets/javascripts/commentsScript.js new file mode 100644 index 000000000..44fbbcb08 --- /dev/null +++ b/app/assets/javascripts/commentsScript.js @@ -0,0 +1,5 @@ +var DANEBOOK = DANEBOOK || {} + +DANEBOOK.comments = { + +} \ No newline at end of file diff --git a/app/assets/javascripts/friendings.coffee b/app/assets/javascripts/friendings.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/friendings.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/friends.coffee b/app/assets/javascripts/friends.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/friends.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/likes.coffee b/app/assets/javascripts/likes.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/likes.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/newsfeed.coffee b/app/assets/javascripts/newsfeed.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/newsfeed.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/photos.coffee b/app/assets/javascripts/photos.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/photos.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/photosScript.js b/app/assets/javascripts/photosScript.js new file mode 100644 index 000000000..9fdda5001 --- /dev/null +++ b/app/assets/javascripts/photosScript.js @@ -0,0 +1,20 @@ +var DANEBOOK = DANEBOOK || {} + +DANEBOOK.photos = { + + init: function(){ + DANEBOOK.photos.setCommentBoxListener(); + }, + + setCommentBoxListener: function(){ + $("#photo-header-bar").on("click",".comment-link", function(event) { + $(event.target).parents('#post-feedback').next().children(".write-comment").toggle(500); + }); + } + +}; + + +$(document).ready(function() { + DANEBOOK.photos.init(); +}); \ No newline at end of file diff --git a/app/assets/javascripts/posts.coffee b/app/assets/javascripts/posts.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/posts.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/postsScript.js b/app/assets/javascripts/postsScript.js new file mode 100644 index 000000000..2c9d7d67f --- /dev/null +++ b/app/assets/javascripts/postsScript.js @@ -0,0 +1,28 @@ +var DANEBOOK = DANEBOOK || {} + +DANEBOOK.posts = { + + init: function(){ + DANEBOOK.posts.setCommentBoxListener(); + }, + + setCommentBoxListener: function(){ + $("#all-previous-posts").on("click",".comment-link", function(event) { + $(event.target).parents('#post-feedback').next().children(".write-comment").toggle(500); + }); + }, + + setPostListener: function() { + $('#post-submit-button').click(function(event){ + event.preventDefault(); + var postText = $("#post_body").val(); + DANEBOOK.ajax.sendPost(postText) + }) + } + +}; + + +$(document).ready(function() { + DANEBOOK.posts.init(); +}); \ No newline at end of file diff --git a/app/assets/javascripts/sessions.coffee b/app/assets/javascripts/sessions.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/sessions.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/static_pages.coffee b/app/assets/javascripts/static_pages.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/static_pages.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/timelines.coffee b/app/assets/javascripts/timelines.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/timelines.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/users.coffee b/app/assets/javascripts/users.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/users.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css new file mode 100644 index 000000000..0ebd7fe82 --- /dev/null +++ b/app/assets/stylesheets/application.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/app/assets/stylesheets/comments.scss b/app/assets/stylesheets/comments.scss new file mode 100644 index 000000000..3722c124e --- /dev/null +++ b/app/assets/stylesheets/comments.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the comments controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/edit_styles.css.scss b/app/assets/stylesheets/edit_styles.css.scss new file mode 100644 index 000000000..3aed8458e --- /dev/null +++ b/app/assets/stylesheets/edit_styles.css.scss @@ -0,0 +1,12 @@ +#single-profile-tab:last-of-type{ + border-right: 2px solid black; +} + +.form-control{ + margin-bottom: 10px; +} + +#save-changes{ + margin-top: 20px; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/app/assets/stylesheets/friendings.scss b/app/assets/stylesheets/friendings.scss new file mode 100644 index 000000000..25e6461f0 --- /dev/null +++ b/app/assets/stylesheets/friendings.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the friendings controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/friends.scss b/app/assets/stylesheets/friends.scss new file mode 100644 index 000000000..8b8aa1c4d --- /dev/null +++ b/app/assets/stylesheets/friends.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the friends controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/friends_styles.css.scss b/app/assets/stylesheets/friends_styles.css.scss new file mode 100644 index 000000000..618b7d2cb --- /dev/null +++ b/app/assets/stylesheets/friends_styles.css.scss @@ -0,0 +1,30 @@ + + + + +#friend-profile{ + border: 2px solid black; + margin-top: 10px; + margin-bottom: 10px; + h5{ + display: inline-block; + position: absolute; + margin-left: 10px; + margin-top: 20px; + } + #friend-profile-picture{ + height: 75px; + display: inline-block; + padding-top: 10px; + padding-bottom: 10px; + } + img{ + height: 75px; + width: 75px; + object_fit: cover; + } + #unfriend-button{ + float:right; + margin-top: 20px; + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/index.css.scss b/app/assets/stylesheets/index.css.scss new file mode 100644 index 000000000..c44a1e9c7 --- /dev/null +++ b/app/assets/stylesheets/index.css.scss @@ -0,0 +1,81 @@ +body{ + padding-bottom: 20px; +} + +main{ + transition: padding 500; +} +.navbar-default{ + background-color: #2679E8; + border: 2px solid black; + .navbar-header { + background-color: #2679E8; + } + + .form-group{ + margin-bottom: -10px; + } + .navbar-brand{ + color: white; + font-size: 35px; + line-height: 40px; + } + button { + background-color: #9FC5F8; + border: 2px solid black; + + } + + #log-in-button{ + padding-top: 28px; + display: inline-block; + } + + p{ + color: white; + } + + input{ + margin-top: -10px; + border: 2px solid black; + + } + .collapse { + background-color: #2679E8; + } +} +main { + #connect{ + margin-top: 50px; + h5 { + color: #555; + line-height: 30px; + } + } + #sign-up{ + input{ + margin: 10px 0px; + } + + .dropdown{ + display: inline-block; + margin-right: 10px + } + label { + margin-top: 7px; + margin-right: 10px; + } + #sign-up-button{ + background-color: #009E0F; + width: 100%; + border: 2px solid black; + } + } + +} +@media only screen and (min-width: 768px) { + main { + margin-top: 64px; } } + + + diff --git a/app/assets/stylesheets/likes.scss b/app/assets/stylesheets/likes.scss new file mode 100644 index 000000000..1f08d329f --- /dev/null +++ b/app/assets/stylesheets/likes.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the likes controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/newsfeed.scss b/app/assets/stylesheets/newsfeed.scss new file mode 100644 index 000000000..a6665bf4b --- /dev/null +++ b/app/assets/stylesheets/newsfeed.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the newsfeed controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/photos.scss b/app/assets/stylesheets/photos.scss new file mode 100644 index 000000000..dcd68e73d --- /dev/null +++ b/app/assets/stylesheets/photos.scss @@ -0,0 +1,83 @@ +// Place all the styles related to the photos controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +#photo-holder{ + height: 150px; + margin-top: 20px; + margin-bottom: 20px; + img{ + height: 150px; + width: 150px; + margin: 0 auto; + + } + p{ + position: relative; + visibility: hidden; + height: 25%; + bottom: 55px; + left: 2px; + width: 146px; + margin: 0 auto; + text-align: center; + background-color: #333; + opacity: 0.8; + color: white; + line-height: 40px; + font-size: 12px; + } +} + +#photo-holder:hover { + p{ + visibility: visible; + } +} + +#photo-show{ + padding-top: 50px; + padding-bottom: 50px; +} + +#photo-show img{ + object-fit: contain; + width: 100%; + height: 400px; +} + +#photo-feedback{ + margin-left: 20px; +} + +#photo-header-bar{ + text-align: center; + margin-top: 10px; + border: 2px solid black; + background-color: #ccc; +} + +#photo-comments-section{ + background: #ccc; + border-top: 2px solid #999; + padding-top: 10px; + p, h6{ + text-align: left; + margin-left: 10px; + } + a{ + img{ + height: 75px; + width: 75px; + } + } + textarea{ + width: 100%; + border: 2px solid black; + margin-top: 25px; + margin-bottom: 5px; + padding-left: 10px; + } + padding-bottom: 10px; + } + diff --git a/app/assets/stylesheets/photos_styles.css.scss b/app/assets/stylesheets/photos_styles.css.scss new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/app/assets/stylesheets/photos_styles.css.scss @@ -0,0 +1 @@ + diff --git a/app/assets/stylesheets/posts.scss b/app/assets/stylesheets/posts.scss new file mode 100644 index 000000000..66a9e6936 --- /dev/null +++ b/app/assets/stylesheets/posts.scss @@ -0,0 +1,7 @@ +// Place all the styles related to the posts controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +.write-comment { + display: none; +} \ No newline at end of file diff --git a/app/assets/stylesheets/sessions.scss b/app/assets/stylesheets/sessions.scss new file mode 100644 index 000000000..7bef9cf82 --- /dev/null +++ b/app/assets/stylesheets/sessions.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the sessions controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/static_pages.scss b/app/assets/stylesheets/static_pages.scss new file mode 100644 index 000000000..91bfee2da --- /dev/null +++ b/app/assets/stylesheets/static_pages.scss @@ -0,0 +1,28 @@ +// Place all the styles related to the static_pages controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + + +nav{ + background-color: #2D77E2 +} + +.navbar-brand{ + background-color: #2D77E2 +} + +.navbar{ + border: 2px solid black; + background-color: #2D77E2; + .navbar-brand{ + color: white; + margin-right: -10px; + } + a{ + color: white; + + } + + + +} diff --git a/app/assets/stylesheets/styles.css.scss b/app/assets/stylesheets/styles.css.scss new file mode 100644 index 000000000..3cbad146f --- /dev/null +++ b/app/assets/stylesheets/styles.css.scss @@ -0,0 +1,241 @@ + + +.form-control{ +} +#cover-photo{ + border: 2px solid black; + padding-right: 0; + padding-left: 0; + .img-responsive{ + width: 100%; + height: 307px; + position: relative; + z-index: 0; + } + +} + +#remember-me{ + display: inline-block +} + +#profile-picture{ + height: 150px; + position: relative; + overflow: hidden; + background-color: #ccc; + z-index: 4; + img{ + position: absolute; + z-index: 0; + left: 50%; + top: 50%; + height: 100%; + width: auto; + -webkit-transform: translate(-50%,-50%); + -ms-transform: translate(-50%,-50%); + transform: translate(-50%,-50%); + } + margin-top: -135px; + margin-left: 5%; + margin-bottom: -5%; + border: solid black 2px; + + +} + + +.profile-name{ + margin-top: -67px; + margin-left: 25%; + h2{ + display: inline-block; + border-bottom: -2px; + color: white; + + } + +} + +.edit-profile-name{ + margin-top: -100px; + margin-left: 25%; + h2{ + display: inline-block; + border-bottom: -2px; + color: white; + + } + +} + + + + +.navbar{ + border: 2px solid black; + background-color: #2D77E2; + .navbar-brand{ + color: white; + margin-right: -10px; + } + a{ + color: white; + + } + + +} + +.btn-primary{ + background-color: #2D77E2; +} + +a{ + color: #2D77E2; +} + + + +#navbar-profile-link{ + text-align: right; + padding-top: 8px; + padding-top: 8px; +} + +#edit-profile-link{ + text-align: right; +} + +#profile-tabs{ + border: 2px solid black; + border-top: 0px; +} + +#single-profile-tab{ + border-right: 2px solid black; + text-align: center; +} + +#single-profile-tab-current{ + background-color: #ccc; + border-right: 2px solid black; + text-align: center; +} + +#single-profile-tab:first-of-type{ + border-left: 2px solid black; +} + +#edit-profile-tab{ + border-right: 0px solid black; + h6{ + text-align: center; + } +} + +@media (max-width:768px){ + #single-profile-tab{ + border: 0px; + h6{ + font-size: 16px; + } + } + #single-profile-tab:first-of-type{ + border: 0px; + h6{ + font-size: 16px; + } + } + #single-profile-tab-current{ + border: 0px; + h6{ + font-size: 16px; + line-height: 30px; + } + + } + #edit-profile-tab{ + h6{ + font-size: 16px; + } + } + #profile-picture{ + margin-top: -220px; + position: relative; + overflow: hidden; + border: 3px solid black; + margin-left: 8%; + img{ + position: absolute; + left: 50%; + top: 50%; + height: 100%; + width: auto; + -webkit-transform: translate(-50%,-50%); + -ms-transform: translate(-50%,-50%); + transform: translate(-50%,-50%); + } + h2{ + padding-left: 20px; + display: block; + color: white; + text-align: center; + } + } + +} +@media (min-width: 769px) and (max-width: 990px){ + #profile-picture{ + margin-top: -220px; + margin-left: 8%; + img{ + display: block; + margin: auto; + } + h2{ + display: block; + color: white; + text-align: center; + + } + } +} + + + +#header-bar{ + text-align: center; + margin-top: 10px; + border: 2px solid black; + background-color: #ccc; + a{ + float: right; + display: inline-block; + margin-top: -42px; + margin-bottom: 5px; + } + h2{ + margin-top: 5px; + } +} + +#basic{ + border: 2px solid black; + border-top: 0px; +} + +#profile-picture-form { + display: inline-block; +} + +#profile-picture-image{ + display: inline-block; +} + +#profile-names{ + display: inline-block; + margin-top: -250px; + margin-left: 25%; + z-index: 5; +} diff --git a/app/assets/stylesheets/timeline_styles.css.scss b/app/assets/stylesheets/timeline_styles.css.scss new file mode 100644 index 000000000..a8a6a17dc --- /dev/null +++ b/app/assets/stylesheets/timeline_styles.css.scss @@ -0,0 +1,153 @@ +#timeline-divider{ + .timeline-content{ + border: 2px solid black; + padding-top: 10px; + border-top: 0px; + h6{ + text-align: center; + } + } + .timeline-title{ + border: 2px solid black; + text-align: center; + background: #ccc; + } + .timeline-title:first-of-type{ + margin-top: 10px; + } + img{ + height: 100%; + width: 100%; + margin-bottom: 10px; + } + + #photo-img-container{ + + width: 33.3333333%; + height: 75px; + overflow: hidden; + margin-bottom: 10px; + } + + #photo-img{ + + object-fit: cover; + height: 75px; + + + } + p{ + text-align: center; + } +} + +#timeline-friends-photos{ + margin-top: 10px; +} + +#single-profile-tab-current{ + border-left: 2px solid black; +} + +@media (max-width: 768px){ + #single-profile-tab-current{ + border: 0px; + } +} + +#post-container{ + border: 2px solid black; + border-top: 0px; + textarea{ + margin: 10px 0px; + width: 100%; + padding-left: 10px; + } +} + +#post-button-container{ + border: 2px solid black; + border-top: 0px; + background-color: #ccc; + a{ + margin: 10px; + border: 2px solid black; + } +} + +#previous-post-container{ + border: 2px solid black; + margin-top: 20px; + #author-info{ + img{ + margin-top: 10px; + display: inline-block; + width: 75px; + height: 75px; + } + h6{ + display: inline-block; + } + } + #post-content{ + p{ + text-align: left; + } + } + #post-feedback{ + background: #ccc; + border-top: 2px solid black; + } + #comments-section{ + background: #ccc; + border-top: 2px solid #999; + padding-top: 10px; + p{ + text-align: left; + } + .comment-image{ + height: 50px; + width: 75px; + } + textarea{ + width: 100%; + border: 2px solid black; + margin-top: 25px; + margin-bottom: 5px; + padding-left: 10px; + } + padding-bottom: 10px; + } +} + + + + +#timeline-friend-img-container{ + + height: 75px; + overflow: hidden; + margin-bottom: 5px; + } + + #timeline-friend-img{ + + object-fit: cover; + height: 75px; + + + } + + + + + + + + + + + + + + diff --git a/app/assets/stylesheets/timelines.scss b/app/assets/stylesheets/timelines.scss new file mode 100644 index 000000000..92f39ca74 --- /dev/null +++ b/app/assets/stylesheets/timelines.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the timelines controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/users.scss b/app/assets/stylesheets/users.scss new file mode 100644 index 000000000..e379d61e3 --- /dev/null +++ b/app/assets/stylesheets/users.scss @@ -0,0 +1,18 @@ +// Place all the styles related to the users controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +#error_explanation { + color: red +} + +.search-bar{ + margin-top: 30px; +} + +.logout{ + margin-top: 18px; + color: white; + font-size: 16px; +} + diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 000000000..d67269728 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 000000000..0ff5442f4 --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 000000000..d66db5c80 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,74 @@ +class ApplicationController < ActionController::Base + protect_from_forgery with: :exception + before_action :require_login + + + + private + + def sign_in(user) + user.regenerate_auth_token + cookies[:auth_token] = user.auth_token + @current_user = user + end + + def permanent_sign_in(user) + user.regenerate_auth_token + cookies.permanent[:auth_token] = user.auth_token + @current_user = user + end + + def sign_out + @current_user = nil + cookies.delete(:auth_token) + end + + def current_user + @current_user ||= User.find_by_auth_token(cookies[:auth_token]) if cookies[:auth_token] + end + helper_method :current_user + + def signed_in_user? + !!current_user + end + helper_method :signed_in_user? + + def require_login + unless signed_in_user? + flash[:danger] = "Not authorized, please sign in!" + redirect_to root_path + end + end + + def real_user_id + params[:user_id] || params[:id] || current_user.id + end + helper_method :real_user_id + + def real_user + User.find(real_user_id) + end + helper_method :real_user + + def user_header_name(user_id) + "#{User.find(user_id).profile.first_name} #{User.find(user_id).profile.last_name}" if User.find(user_id).profile + end + helper_method :user_header_name + + def require_current_user + unless params[:id] == current_user.id.to_s || params[:user_id] == current_user.id.to_s + flash[:danger] = "You're not authorized for that action!" + redirect_to root_path + end + end + + def find_like_id(user_id, likeable_id, likeable_type) + like = Like.where("user_id = ? AND likeable_id = ? AND likeable_type = ?", user_id, likeable_id, likeable_type) + like.ids[0] + end + helper_method :find_like_id + + + + +end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb new file mode 100644 index 000000000..1b344b1cd --- /dev/null +++ b/app/controllers/comments_controller.rb @@ -0,0 +1,45 @@ +class CommentsController < ApplicationController + + + def create + @new_comment = current_user.comments_written.new(comment_params) + if @new_comment.save + @content_id = comment_params[:commentable_id]; + @content_type = comment_params[:commentable_type]; + if comment_params[:commentable_type] == "Post" + @object_maker = Post.find(comment_params[:commentable_id]).author + else + @object_maker = Photo.find(comment_params[:commentable_id]).user + end + if @object_maker != current_user + User.comment_email(@object_maker.id, current_user.id, @new_comment.id, params[:commentable_id]) + end + respond_to :js + else + flash[:danger] = "Your comment could not be posted" + redirect_back(fallback_location: root_path) + end + end + + + def destroy + @comment = Comment.find(params[:id]) + if current_user.id == @comment.user_id && @comment.destroy! + flash[:success] = "Your comment has been deleted" + redirect_back(fallback_location: root_path) + else + flash[:danger] = "Your comment could not be deleted" + redirect_back(fallback_location: root_path) + end + + end + + + private + + def comment_params + params.require(:comment).permit(:body, :commentable_id, :commentable_type) + end + + +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/controllers/friendings_controller.rb b/app/controllers/friendings_controller.rb new file mode 100644 index 000000000..0755eceec --- /dev/null +++ b/app/controllers/friendings_controller.rb @@ -0,0 +1,31 @@ +class FriendingsController < ApplicationController + + + def create + friending_recipient = User.find(params[:friended_id]) + + if current_user.friended_users << friending_recipient && current_user != friending_recipient + flash[:success] = "You've friended #{friending_recipient.profile.first_name}" + redirect_back(fallback_location: root_path) + else + flash[:danger] = "Could not friend #{friending_recipient.profile.first_name}" + redirect_back(fallback_location: root_path) + end + end + + + def destroy + friending_recipient = User.find(params[:id]) + if current_user.friended_users.delete(friending_recipient) + flash[:success] = "You've unfriended #{friending_recipient.profile.first_name}" + redirect_back(fallback_location: root_path) + else + flash[:danger] = "Could not unfriend #{friending_recipient.profile.first_name}" + redirect_back(fallback_location: root_path) + end + end + + private + + +end diff --git a/app/controllers/friends_controller.rb b/app/controllers/friends_controller.rb new file mode 100644 index 000000000..824bfa309 --- /dev/null +++ b/app/controllers/friends_controller.rb @@ -0,0 +1,7 @@ +class FriendsController < ApplicationController + + def index + @user = User.find(params[:user_id]) + @friends = @user.friends + end +end diff --git a/app/controllers/likes_controller.rb b/app/controllers/likes_controller.rb new file mode 100644 index 000000000..7b7e63039 --- /dev/null +++ b/app/controllers/likes_controller.rb @@ -0,0 +1,44 @@ +class LikesController < ApplicationController + + + + + def create + @like = Like.new(like_params) + @like.user_id = current_user.id + @content_id = like_params[:likeable_id] + @content_type = like_params[:likeable_type] + if @like.save! + @id = @like.id + respond_to :js + else + flash.now[:danger] = "Could not like that post" + redirect_back(fallback_location: root_path) + end + end + + def destroy + @like = Like.find(params[:id]) + @content_id = @like.likeable_id + @content_type = @like.likeable_type + if current_user.id == @like.user_id && @like.destroy + respond_to :js + else + flash.now[:danger] = "Coult not unlike that post" + redirect_back(fallback_location: root_path) + end + end + + private + + def like_params + params.permit(:likeable_type, :likeable_id) + end + + + + + + + +end diff --git a/app/controllers/newsfeed_controller.rb b/app/controllers/newsfeed_controller.rb new file mode 100644 index 000000000..0823dde32 --- /dev/null +++ b/app/controllers/newsfeed_controller.rb @@ -0,0 +1,8 @@ +class NewsfeedController < ApplicationController + + def index + @posts = current_user.friends_posts + @comment = current_user.comments_written.new + end + +end diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb new file mode 100644 index 000000000..644de9b56 --- /dev/null +++ b/app/controllers/photos_controller.rb @@ -0,0 +1,54 @@ +class PhotosController < ApplicationController + + + def index + @user = User.find(params[:id]) + @photos = @user.photos + end + + def new + @photo = current_user.photos.build + end + + def show + @photo = Photo.find(params[:id]) + @photo_id = @photo.id.to_s + @user_id = @photo.user_id + @comment = Comment.new + end + + def create + @photo = current_user.photos.build(photo_params) + if @photo.save + flash[:success] = "Your photo has been uploaded!" + redirect_to photos_path(id: current_user) + else + flash[:danger] = "Your photo could not be uploaded" + redirect_to photos_path(id: current_user) + end + end + + + def update + + end + + def destroy + @photo = Photo.find(params[:id]) + if @photo.user == current_user && @photo.destroy + flash[:success] = "Photo deleted" + redirect_to user_path(current_user) + else + flash[:error] = "Could not delete photo" + redirect_back(fallback_location: root_path) + end + + end + + private + + def photo_params + params.require(:photo).permit(:image) + end + +end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb new file mode 100644 index 000000000..da9bf6d6a --- /dev/null +++ b/app/controllers/posts_controller.rb @@ -0,0 +1,41 @@ +class PostsController < ApplicationController + + def create + @new_post = current_user.posts_written.new(post_params) + @new_post.post_receiver_id = session[:receiver_id] + if @new_post.save + @post = current_user.posts_written.new + @comment = current_user.comments_written.new + respond_to :js + else + flash[:danger] = "Your message could not be posted :(" + redirect_back(fallback_location: root_path) + end + end + + def edit + + end + + def update + + end + + def destroy + @post = Post.find(params[:id]) + if current_user.id == @post.post_author_id && @post.destroy + flash[:success] = "Your post has been deleted" + redirect_back(fallback_location: root_path) + else + flash[:danger] = "Your post could not be deleted" + redirect_back(fallback_location: root_path) + end + end + + private + + def post_params + params.require(:post).permit(:post_author_id, :post_receiver_id, :body) + end + +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 000000000..6dbdacebf --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,25 @@ +class SessionsController < ApplicationController + skip_before_action :require_login, only: [:new, :create] + + def create + @user = User.find_by_email(params[:email]) + if @user && @user.authenticate(params[:password]) + if params[:remember_me] + permanent_sign_in(@user) + else + sign_in(@user) + end + flash[:success] = "You have successfully signed in" + redirect_to newsfeed_index_path + else + flash[:danger] = "Incorrect log-in information. Please try again" + redirect_to new_user_path + end + end + + def destroy + sign_out + flash[:success] = "You've successfully signed out" + redirect_to new_user_path + end +end diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb new file mode 100644 index 000000000..19579d670 --- /dev/null +++ b/app/controllers/static_pages_controller.rb @@ -0,0 +1,29 @@ +class StaticPagesController < ApplicationController + skip_before_action :require_login, only: [:home] + + + + def home + if signed_in_user? + redirect_to user_timeline_path(current_user) + end + + end + + def timeline + + end + + def photos + + end + + def about_edit + + end + + def about + + + end +end diff --git a/app/controllers/timelines_controller.rb b/app/controllers/timelines_controller.rb new file mode 100644 index 000000000..f341d24f8 --- /dev/null +++ b/app/controllers/timelines_controller.rb @@ -0,0 +1,13 @@ +class TimelinesController < ApplicationController + + def show + if User.find_by_id(real_user_id) == nil + flash[:danger] = "Sorry, that user does not exist. But if you sign up your friends, someday we'll get there!" + redirect_to user_timeline_path(current_user) + end + @post = current_user.posts_written.new + @comment = current_user.comments_written.new + @timeline_user = User.find(params[:user_id]) + session[:receiver_id] = @timeline_user.id + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 000000000..881c95ce6 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,85 @@ +class UsersController < ApplicationController + skip_before_action :require_login, only: [:new, :create] + before_action :require_current_user, only: [:edit, :update, :destroy] + + def index + if params[:search] + @users = User.search(params[:search], current_user.id) + @search_terms = params[:search] + else + @users = User.all + end + end + + def new + @user = User.new + if signed_in_user? + redirect_to newsfeed_index_path + end + end + + def create + @user = User.new(user_params) + if @user.save + User.welcome_email(@user.id) + sign_in(@user) + flash[:success] = "Your account has been created" + redirect_to user_timeline_path(@user) + else + flash.now[:danger] = "Account could not be created" + render :new + end + end + + def show + if User.find_by_id(real_user_id) == nil + flash[:danger] = "Sorry, that user does not exist. But if you sign up your friends, someday we'll get there!" + redirect_to user_timeline_path(current_user) + end + @user = User.find(params[:id]) + end + + def edit + @user = current_user + end + + def update + @user = current_user + if @user.update(user_params) + flash[:success] = "Your profile has been updated" + redirect_to user_path(current_user) + else + flash.now[:danger] = "Your profile could not be updated" + render :edit + end + end + + def destroy + + end + + + private + + def user_params + params.require(:user).permit(:email, + :password, + :password_confirmation, + {:profile_attributes => [ + :first_name, + :last_name, + :birthday, + :gender, + :college, + :hometown, + :currently_lives, + :telephone, + :words_to_live_by, + :about_me, + :profile_picture, + :cover_photo_id, + :prof_photo_id + ]}) + end + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 000000000..de6be7945 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb new file mode 100644 index 000000000..0ec9ca5f2 --- /dev/null +++ b/app/helpers/comments_helper.rb @@ -0,0 +1,2 @@ +module CommentsHelper +end diff --git a/app/helpers/friendings_helper.rb b/app/helpers/friendings_helper.rb new file mode 100644 index 000000000..fce356995 --- /dev/null +++ b/app/helpers/friendings_helper.rb @@ -0,0 +1,2 @@ +module FriendingsHelper +end diff --git a/app/helpers/friends_helper.rb b/app/helpers/friends_helper.rb new file mode 100644 index 000000000..0b69e9bce --- /dev/null +++ b/app/helpers/friends_helper.rb @@ -0,0 +1,2 @@ +module FriendsHelper +end diff --git a/app/helpers/likes_helper.rb b/app/helpers/likes_helper.rb new file mode 100644 index 000000000..a78a75964 --- /dev/null +++ b/app/helpers/likes_helper.rb @@ -0,0 +1,2 @@ +module LikesHelper +end diff --git a/app/helpers/newsfeed_helper.rb b/app/helpers/newsfeed_helper.rb new file mode 100644 index 000000000..bf0034e96 --- /dev/null +++ b/app/helpers/newsfeed_helper.rb @@ -0,0 +1,2 @@ +module NewsfeedHelper +end diff --git a/app/helpers/photos_helper.rb b/app/helpers/photos_helper.rb new file mode 100644 index 000000000..0a10d472b --- /dev/null +++ b/app/helpers/photos_helper.rb @@ -0,0 +1,2 @@ +module PhotosHelper +end diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb new file mode 100644 index 000000000..a7b8cec89 --- /dev/null +++ b/app/helpers/posts_helper.rb @@ -0,0 +1,2 @@ +module PostsHelper +end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 000000000..309f8b2eb --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/helpers/static_pages_helper.rb b/app/helpers/static_pages_helper.rb new file mode 100644 index 000000000..2d63e79e6 --- /dev/null +++ b/app/helpers/static_pages_helper.rb @@ -0,0 +1,2 @@ +module StaticPagesHelper +end diff --git a/app/helpers/timelines_helper.rb b/app/helpers/timelines_helper.rb new file mode 100644 index 000000000..1f1a4f076 --- /dev/null +++ b/app/helpers/timelines_helper.rb @@ -0,0 +1,2 @@ +module TimelinesHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 000000000..2310a240d --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 000000000..a009ace51 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 000000000..286b2239d --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 000000000..436316f1e --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,15 @@ +class UserMailer < ApplicationMailer + default :from => "support@danebook.com" + + def welcome(user) + @user = user + mail(to: @user.email, subject: "Welcome to Danebook!") + end + + def comment(owner_user, comment_user, comment) + @comment = comment.body + @owner_user = owner_user + @comment_user = comment_user + mail(to: @owner_user.email, subject: "Someone commented on your post!") + end +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..cf91736c6 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,29 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true + + + def real_likes + Like.where("likeable_id = ? AND likeable_type = ?", self.id, self.class.name) + end + + def display_likes + likes = self.real_likes + like_total = likes.count + liker_array = [] + likes[0..2].each do |like| + liker_array << like.user_id + like_total -= 1 + end + if like_total == 1 + return_string = "and 1 other person like this" + elsif like_total > 1 + return_string = "and #{like_total} others like this" + elsif liker_array.length == 1 + return_string = "likes this" + else + return_string = "like this" + end + [liker_array, return_string] + end + +end diff --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100644 index 000000000..e27027de7 --- /dev/null +++ b/app/models/comment.rb @@ -0,0 +1,7 @@ +class Comment < ApplicationRecord + belongs_to :user, :foreign_key => :user_id + belongs_to :commentable, :polymorphic => true + has_many :comments, :as => :commentable + has_many :likes, :as => :likeable, :source => :likeable_id, source_type: "Comment" + +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/models/friending.rb b/app/models/friending.rb new file mode 100644 index 000000000..fe517a6b5 --- /dev/null +++ b/app/models/friending.rb @@ -0,0 +1,7 @@ +class Friending < ApplicationRecord + + belongs_to :friend_initiator, :foreign_key => :friender_id, :class_name => "User" + belongs_to :friend_recipient, :foreign_key => :friended_id, :class_name => "User" + + validates :friended_id, :uniqueness => { :scope => :friender_id } +end diff --git a/app/models/like.rb b/app/models/like.rb new file mode 100644 index 000000000..b1747882e --- /dev/null +++ b/app/models/like.rb @@ -0,0 +1,19 @@ +class Like < ApplicationRecord + belongs_to :user, :foreign_key => :user_id + belongs_to :likeable, :polymorphic => true + + + + private + + def self.find_likable_type(path) + array = path.split("/") + if array[1] == "comments" + return "Comment" + elsif array[1] == "posts" + return "Post" + end + end + + +end diff --git a/app/models/photo.rb b/app/models/photo.rb new file mode 100644 index 000000000..6c2900921 --- /dev/null +++ b/app/models/photo.rb @@ -0,0 +1,11 @@ +class Photo < ApplicationRecord + has_one :post, :as => :postable + has_one :used_as_profile, class_name: "Profile", foreign_key: :prof_photo_id, dependent: :nullify + has_one :used_as_cover, class_name: "Profile", foreign_key: :cover_photo_id, dependent: :nullify + has_many :comments, :as => :commentable + has_many :likes, :as => :likeable, :source => :likeable_id, source_type: "Photo" + belongs_to :user + + has_attached_file :image, :styles => { :index => "150x120", :timeline => "60x50", :profile => "150x150", :post => "75x75", :cover => "990x300" }, default_url: "https://s3.amazonaws.com/viking_education/web_development/web_app_eng/icon_photo_small.png" + validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/ +end diff --git a/app/models/post.rb b/app/models/post.rb new file mode 100644 index 000000000..e52ac36c8 --- /dev/null +++ b/app/models/post.rb @@ -0,0 +1,12 @@ +class Post < ApplicationRecord + belongs_to :author, :foreign_key => :post_author_id, :class_name => "User" + belongs_to :receiver, :foreign_key => :post_receiver_id, :class_name => "User", optional: true + has_many :comments, :as => :commentable + has_many :likes, :as => :likeable, :source => :likeable_id, source_type: "Post" + validates :body, presence: true + + + + + +end diff --git a/app/models/post_text.rb b/app/models/post_text.rb new file mode 100644 index 000000000..2b258a091 --- /dev/null +++ b/app/models/post_text.rb @@ -0,0 +1,3 @@ +class PostText < ApplicationRecord + has_one :post, :as => :postable +end diff --git a/app/models/profile.rb b/app/models/profile.rb new file mode 100644 index 000000000..902125675 --- /dev/null +++ b/app/models/profile.rb @@ -0,0 +1,43 @@ +class Profile < ApplicationRecord + belongs_to :user, optional: true + belongs_to :prof_photo, optional: true, class_name: "Photo" + belongs_to :cover_photo, optional: true, class_name: "Photo" + accepts_nested_attributes_for :cover_photo + accepts_nested_attributes_for :prof_photo + validates :first_name, + :length => {:maximum => 40}, allow_blank: true, allow_nil: true + + validates :last_name, + :length => {:maximum => 40}, allow_blank: true, allow_nil: true + + validates :college, + :length => {:maximum => 40}, allow_blank: true, allow_nil: true + + validates :hometown, + :length => {:maximum => 40}, allow_blank: true, allow_nil: true + + validates :currently_lives, + :length => {:maximum => 40}, allow_blank: true, allow_nil: true + + validates :words_to_live_by, + :length => {:maximum => 300}, allow_blank: true, allow_nil: true + + validates :about_me, + :length => {:maximum => 300}, allow_blank: true, allow_nil: true + + validates_date :birthday, + :message => "Please enter a real date", + :before => lambda {Date.current}, + :before_message => "Get real. You can't be born in the future!", + allow_nil: true, + allow_blank: true + validates :telephone, + :numericality => true, + :length => { :minimum => 10, :maximum => 15 }, + :on => :update, + allow_nil: true, + allow_blank: true + + + +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 000000000..573ef1f2e --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,105 @@ +class User < ApplicationRecord + before_create :generate_token + + has_secure_password + validates :email, + :presence => {:message => "Please enter an email"}, + :format => { :with => /@/, :message => "Please enter a valid email address" }, + :uniqueness => true + validates :password, + :length => {:minimum => 6}, + :on => :create + has_one :profile, dependent: :destroy + + has_many :photos, foreign_key: :user_id + + + + accepts_nested_attributes_for :profile, :update_only => true + has_many :posts_written, :foreign_key => :post_author_id, :class_name => "Post" + has_many :posts_received, :foreign_key => :post_receiver_id, :class_name => "Post" + has_many :comments_written, :foreign_key => :user_id, :class_name => "Comment" + has_many :likes_given, :foreign_key => :user_id, :class_name => "Like" + has_many :initiated_friendings, :foreign_key => :friender_id, :class_name => "Friending" + has_many :friended_users, :through => :initiated_friendings, :source => :friend_recipient + + has_many :received_friendings, :foreign_key => :friended_id, :class_name => "Friending" + has_many :users_friended_by, :through => :received_friendings, :source => :friend_initiator + + def generate_token + begin + self[:auth_token] = SecureRandom.urlsafe_base64 + end while User.exists?(:auth_token => self[:auth_token]) + end + + def regenerate_auth_token + self.auth_token = nil + generate_token + self.save! + end + + def likes_post?(id, type) + self.likes_given.where("likeable_id = ? AND likeable_type = ?", id, type) + end + + def friend_count + self.friends.size + end + + def friends + (self.friended_users + self.users_friended_by).uniq + end + + def self.search(search, id) + users = [] + if search + all_terms = search.split + all_terms.each do |term| + term_users = User.joins(:profile).where('first_name ILIKE ? OR last_name ILIKE ?', "%#{term}%", "%#{term}%") + term_users.each do |term_user| + users << term_user + end + end + users.uniq + else + User.all + end + end + + def friends_posts + friends = self.friends + Post.where(:post_author_id => friends).order(created_at: :desc) + end + + def profile_picture + photo = self.profile.prof_photo + photo.image + end + + def cover_photo + photo = self.profile.cover_photo + photo.image + end + private + class << self + def welcome_email(id) + user = User.find(id) + UserMailer.welcome(user).deliver + end + + handle_asynchronously :welcome_email, run_at: Proc.new { 5.seconds.from_now } + + def comment_email(owner_id, commenter_id, comment_id, post_id) + owner_user = User.find(owner_id) + comment_user = User.find(commenter_id) + comment = Comment.find(comment_id) + UserMailer.comment(owner_user, comment_user, comment).deliver! + end + + handle_asynchronously :comment_email, run_at: Proc.new {5.seconds.from_now} + + end + + + +end diff --git a/app/models/video.rb b/app/models/video.rb new file mode 100644 index 000000000..4ea6b2742 --- /dev/null +++ b/app/models/video.rb @@ -0,0 +1,3 @@ +class Video < ApplicationRecord + has_one :post, :as => :postable +end diff --git a/app/views/comments/create.js.erb b/app/views/comments/create.js.erb new file mode 100644 index 000000000..c867f6cb1 --- /dev/null +++ b/app/views/comments/create.js.erb @@ -0,0 +1,8 @@ +console.log("Hello!"); +var type = "<%= @content_type %>"; +var id = "<%= @content_id %>"; +var post = ($("[" + type +"-id = " + id + "]")); +var newComment = "<%= escape_javascript(render partial: 'shared/comment_box', locals: {comment: @new_comment}) %>"; +post.children('#comments-section, #photo-comments-section').prepend(newComment); +$('#comment_body').val(""); +console.log("Goodbye!"); diff --git a/app/views/friends/index.html.erb b/app/views/friends/index.html.erb new file mode 100644 index 000000000..4409653b0 --- /dev/null +++ b/app/views/friends/index.html.erb @@ -0,0 +1,25 @@ + +
+
+ + <%= render partial: "shared/cover_and_prof", locals: {user: @user} %> + + <%= render "shared/nav_links" %> +
+ +
+ +
+

Friends

+
+ +
+
+ <% @friends.each do |friend| %> + <%= render partial: "shared/friend_page", locals: {user: friend} %> + <% end %> +
+
+
+ +
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 000000000..adf2ea2e9 --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,30 @@ + + + + ProjectDanebook + <%= csrf_meta_tags %> + + + + + + + + + + + + + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> + <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> + + + + + + + <%= render "shared/navbar" %> + <%= render "shared/flash" %> + <%= yield %> + + diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 000000000..cbd34d2e9 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 000000000..37f0bddbd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/app/views/likes/create.js.erb b/app/views/likes/create.js.erb new file mode 100644 index 000000000..c7e0df87c --- /dev/null +++ b/app/views/likes/create.js.erb @@ -0,0 +1,15 @@ +console.log("hello!!"); +var type = "<%= @content_type %>"; +var id = "<%= @content_id %>"; +var post = $("[" + type +"-id = " + id + "]"); +post.find('a.like-button').remove(); +var likeID = "/likes/" + "<%= @id %>" +var unlike = $('').addClass('unlike-button') + .attr('rel', 'nofollow') + .attr('data-method', 'delete') + .attr('href', likeID) + .attr('data-remote', "true") + .html('Unlike'); +console.log(unlike) +post.find('#post-feedback .col-xs-1 h6').append(unlike); +post.find('#comment-feedback .col-xs-1 h6').append(unlike); diff --git a/app/views/likes/destroy.js.erb b/app/views/likes/destroy.js.erb new file mode 100644 index 000000000..c4ec20d2b --- /dev/null +++ b/app/views/likes/destroy.js.erb @@ -0,0 +1,14 @@ +console.log("hello!!"); +var type = "<%= @content_type %>"; +var id = "<%= @content_id %>"; +var post = $("[" + type +"-id = " + id + "]"); +var href = "/likes?likeable_id=" + id + "&likeable_type=" + type; +post.find('a.unlike-button').remove(); +var like = $('').addClass('like-button') + .attr('rel', 'nofollow') + .attr('data-method', 'post') + .attr('href', href) + .attr('data-remote', "true") + .html('Like'); +post.find('#post-feedback .col-xs-1 h6').append(like); +post.find('#comment-feedback .col-xs-1 h6').append(like); \ No newline at end of file diff --git a/app/views/newsfeed/index.html.erb b/app/views/newsfeed/index.html.erb new file mode 100644 index 000000000..e26580c89 --- /dev/null +++ b/app/views/newsfeed/index.html.erb @@ -0,0 +1,31 @@ +
+
+ + <%= render partial: "shared/cover_and_prof", locals: {user: current_user.id} %> + + <%= render "shared/nav_links" %> +
+
+
+

Newsfeed

+
+
+
+
+
+
+
+
+ <% @posts.each do |post| %> + <%= render partial: "shared/post_box", locals: {post: post} %> + <% end %> +
+
+
+
+
+
+
+
+
+ diff --git a/app/views/photos/index.html.erb b/app/views/photos/index.html.erb new file mode 100644 index 000000000..8e22ded5c --- /dev/null +++ b/app/views/photos/index.html.erb @@ -0,0 +1,28 @@ + +
+
+ + <%= render partial: "shared/cover_and_prof", locals: {user: @user} %> + + <%= render "shared/nav_links" %> +
+
+ +
+

Photos

+ <% if current_user.id == @user.id %> + <%= link_to "Add Photo!", new_photo_path(id: real_user_id), class:"btn btn-primary", role:"button" %> + <% end %> +
+ + +
+
+ <% @photos.each do |photo| %> + <%= render partial: "shared/photo_box", locals: {user: @user, photo: photo} %> + <% end %> +
+
+
+ +
\ No newline at end of file diff --git a/app/views/photos/new.html.erb b/app/views/photos/new.html.erb new file mode 100644 index 000000000..2197e7816 --- /dev/null +++ b/app/views/photos/new.html.erb @@ -0,0 +1,20 @@ +
+
+ + <%= render partial: "shared/cover_and_prof", locals: {user: @user} %> + + <%= render "shared/nav_links" %> +
+
+ +
+

Photos

+
+
+ <%= simple_form_for [current_user.photos.build] do |photo_field| %> + <%= photo_field.input :image %> + <%= photo_field.submit %> + <% end %> +
+
+
\ No newline at end of file diff --git a/app/views/photos/show.html.erb b/app/views/photos/show.html.erb new file mode 100644 index 000000000..d3155d2b3 --- /dev/null +++ b/app/views/photos/show.html.erb @@ -0,0 +1,69 @@ + +
+
+ + <%= render partial: "shared/cover_and_prof", locals: {user: @user} %> + + <%= render "shared/nav_links" %> +
+
+ +
+

Photo

+ <% if current_user.id == @user_id %> + <%= form_for current_user do |user_fields| %> + <%= user_fields.fields_for :profile do |profile_fields| %> + <%= profile_fields.label :prof_photo_id, "Make this your profile picture" %> + <%= profile_fields.check_box :prof_photo_id, {}, "#{@photo_id}", nil %> + + <%= profile_fields.label :cover_photo_id, "Make this your cover picture" %> + <%= profile_fields.check_box :cover_photo_id, {}, "#{@photo_id}", nil %> + <%= profile_fields.submit %> + <% end %> + <% end %> + <% end %> +
+
+ <%= image_tag @photo.image.url %> +
+
+
+
+ <% if current_user.likes_post?(@photo.id, "Photo").empty? %> +
<%= link_to "Like", likes_path(likeable_id: @photo.id, likeable_type: "Photo"), remote: true, method: 'post', class: 'like-button' %>
+ <% else %> +
<%= link_to "Unlike", like_path(find_like_id(current_user.id, @photo.id, "Photo")), remote: true, method: 'delete', class: 'unlike-button' %>
+ <% end %> +
+
+ <%= render partial: "shared/like_count", locals: {content: @photo} %> +
+
+ <% if @photo.user_id == current_user.id %> + <%= link_to "Delete Photo", photo_path(@photo), method: :delete %> + <% end %> +
+
+
+
+ <% @photo.comments.reverse.each do |comment| %> + <%= render partial: "shared/photo_comment_box", locals: {comment: comment} %> + <% end %> +
+ <%= simple_form_for @comment, remote: true do |comment_field| %> + <%= comment_field.hidden_field :commentable_type, :value => "Photo" %> + <%= comment_field.hidden_field :commentable_id, :value => "#{@photo.id}" %> + <%= comment_field.input :body, class:"form-control", label: false, input_html: {rows: "1"}, placeholder: "Write a comment..." %> +
+ <%= comment_field.submit "Post comment", class:"btn btn-primary btn-sm" %> +
+ <% end %> +
+
+
+
+ + +
\ No newline at end of file diff --git a/app/views/posts/create.js.erb b/app/views/posts/create.js.erb new file mode 100644 index 000000000..44b115e59 --- /dev/null +++ b/app/views/posts/create.js.erb @@ -0,0 +1,2 @@ +$("#all-previous-posts").prepend("<%= escape_javascript(render partial: 'shared/post_box', locals: {post: @new_post}) %>"); +$("#post_body").val(""); diff --git a/app/views/shared/_comment_box.html.erb b/app/views/shared/_comment_box.html.erb new file mode 100644 index 000000000..8f35586a3 --- /dev/null +++ b/app/views/shared/_comment_box.html.erb @@ -0,0 +1,39 @@ + +
+ <%= link_to user_path(comment.user_id) do %> + <% if comment.user.profile.prof_photo_id %> + <%= image_tag comment.user.profile_picture.url(:profile) %> + <% else %> + + <% end %> + <% end %> +
+ +
+
<%= link_to user_header_name(comment.user_id), user_path(comment.user_id) %> + Posted on <%= comment.created_at.strftime("%m/%d/%Y") %>
+

<%= comment.body %>

+
+
+ + <% if current_user.likes_post?(comment.id, "Comment").empty? %> +
+ <%= link_to "Like", likes_path(likeable_id: comment.id, likeable_type: "Comment"), remote: true, method: 'post', class: 'like-button' %>
+ <% else %> +
+ <%= link_to "Unlike", like_path(find_like_id(current_user.id, comment.id, "Comment")), remote: true, method: 'delete', class: 'unlike-button' %> +
+ <% end %> +
+
+ +
+
<%= render partial: "shared/like_count", locals: {content: comment} %>
+
+
+ <% if comment.user_id == current_user.id %> +
<%= link_to "Delete Comment", comment_path(comment), method: :delete %>
+ <% end %> +
+
+
\ No newline at end of file diff --git a/app/views/shared/_cover_and_prof.html.erb b/app/views/shared/_cover_and_prof.html.erb new file mode 100644 index 000000000..e2b7d484c --- /dev/null +++ b/app/views/shared/_cover_and_prof.html.erb @@ -0,0 +1,20 @@ +
+ <% if real_user.profile.cover_photo_id %> + <%= image_tag real_user.cover_photo.url, class:"img-responsive" %> + <% else %> + <%= image_tag "cover_photo.jpg", class:"img-responsive" %> + <% end %> +
+ +
+ <% if real_user.profile.prof_photo_id %> + <%= image_tag real_user.profile_picture.url, id:"profile-picture-img" %> + <% else %> + + <% end %> +
+
+

<%= user_header_name(real_user_id) %>

+
+
+
\ No newline at end of file diff --git a/app/views/shared/_flash.html.erb b/app/views/shared/_flash.html.erb new file mode 100644 index 000000000..85df9cba8 --- /dev/null +++ b/app/views/shared/_flash.html.erb @@ -0,0 +1,6 @@ +<% flash.each do |type, message| %> +
alert-dismissible" role="alert"> + + <%= message %> +
+<% end %> diff --git a/app/views/shared/_friend_page.html.erb b/app/views/shared/_friend_page.html.erb new file mode 100644 index 000000000..5fbce7db7 --- /dev/null +++ b/app/views/shared/_friend_page.html.erb @@ -0,0 +1,19 @@ +
+
+
+ + <% if user.profile.prof_photo_id %> + <%= image_tag user.profile_picture.url(:post), id:"friend-page-img" %> + <% else %> + + <% end %> + +
<%= link_to user_header_name(user.id), user_path(user) %>
<%= user.friend_count %> Friends
+ <% if current_user.friends.include?(user) %> + <%= link_to "Unfriend me", friending_path(user.id), method: 'delete', class: "btn btn-info", id:"unfriend-button", role:"button" %> + <% elsif current_user.friends.exclude?(user) %> + <%= link_to "Friend me!", friendings_path(friended_id: user.id), method: 'post', class: "btn btn-info", id:"unfriend-button", role:"button" %> + <% end %> +
+
+
\ No newline at end of file diff --git a/app/views/shared/_like_count.html.erb b/app/views/shared/_like_count.html.erb new file mode 100644 index 000000000..936a59693 --- /dev/null +++ b/app/views/shared/_like_count.html.erb @@ -0,0 +1,9 @@ +<% unless content.real_likes.count == 0 %> + <% content.display_likes[0].each_with_index do |user_id, index| %> + <%= link_to user_header_name(user_id), user_path(user_id) %> + <% unless index == content.display_likes[0].length - 1 %> + <%= "," %> + <% end %> + <% end %> + <%= content.display_likes[1] %> +<% end %> diff --git a/app/views/shared/_nav_links.html.erb b/app/views/shared/_nav_links.html.erb new file mode 100644 index 000000000..673e3014b --- /dev/null +++ b/app/views/shared/_nav_links.html.erb @@ -0,0 +1,29 @@ +
+
+
+
+
+ <%= link_to "Timeline", user_timeline_path(real_user_id), class: "h6" %> +
+
+ <%= link_to "About", user_path(real_user_id), class: "h6" %> +
+
+ <%= link_to "Photos (#{real_user.photos.count})", photos_path(id: real_user_id), class: "h6" %> +
+
+ <%= link_to "Friends (#{real_user.friend_count})", user_friends_path(real_user_id), class: "h6" %> +
+
+ <% if real_user_id == current_user.id.to_s %> + <%= link_to "Edit Profile", edit_user_path(real_user_id), class: "h6" %> + <% elsif current_user.friends.include?(real_user) %> + <%= link_to "Unfriend #{real_user.profile.first_name}", friending_path(real_user_id), method: 'delete', class: "btn btn-primary btn-xs friend-button", role: "button" %> + <% else %> + <%= link_to "Friend #{real_user.profile.first_name}", friendings_path(friended_id: real_user_id), method: :post, class: "btn btn-primary btn-xs unfriend-button", role: "button" %> + <% end %> +
+
+
+
+
\ No newline at end of file diff --git a/app/views/shared/_navbar.html.erb b/app/views/shared/_navbar.html.erb new file mode 100644 index 000000000..dc789c6d7 --- /dev/null +++ b/app/views/shared/_navbar.html.erb @@ -0,0 +1,69 @@ + <% if signed_in_user? %> + + + +<% else %> + +<% end %> + diff --git a/app/views/shared/_photo_box.html.erb b/app/views/shared/_photo_box.html.erb new file mode 100644 index 000000000..bf247bdc0 --- /dev/null +++ b/app/views/shared/_photo_box.html.erb @@ -0,0 +1,11 @@ +
+
+
+ <%= link_to photo_path(user_id: photo.user.id, id: photo.id), id:"photo-holder" do %> + <%= image_tag photo.image.url, class:"img-responsive" %> + +

Uploaded on <%= photo.created_at.to_date %>

+ <% end %> +
+
+
\ No newline at end of file diff --git a/app/views/shared/_photo_comment_box.html.erb b/app/views/shared/_photo_comment_box.html.erb new file mode 100644 index 000000000..88a75e7dc --- /dev/null +++ b/app/views/shared/_photo_comment_box.html.erb @@ -0,0 +1,36 @@ + +
+ <%= link_to user_path(comment.user_id) do %> + <% if comment.user.profile.prof_photo_id %> + <%= image_tag comment.user.profile_picture.url(:profile) %> + <% else %> + + <% end %> + <% end %> +
+ +
+
<%= link_to user_header_name(comment.user_id), user_path(comment.user_id) %> + Posted on <%= comment.created_at.strftime("%m/%d/%Y") %>
+

<%= comment.body %>

+
+
+
+ <% if current_user.likes_post?(comment.id, "Comment").empty? %> + <%= link_to "Like", likes_path(likeable_id: comment.id, likeable_type: "Comment"), method: 'post', remote: true, class: 'like-button' %>
+ <% else %> + <%= link_to "Unlike", like_path(find_like_id(current_user.id, comment.id, "Comment")), method: 'delete', remote: true, class: 'unlike-button' %> + <% end %> + +
+ +
+
<%= render partial: "shared/like_count", locals: {content: comment} %>
+
+
+ <% if comment.user_id == current_user.id %> +
<%= link_to "Delete Comment", comment_path(comment), method: :delete %>
+ <% end %> +
+
+
\ No newline at end of file diff --git a/app/views/shared/_post_box.html.erb b/app/views/shared/_post_box.html.erb new file mode 100644 index 000000000..a8333b045 --- /dev/null +++ b/app/views/shared/_post_box.html.erb @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/app/views/shared/_timeline_friends.html.erb b/app/views/shared/_timeline_friends.html.erb new file mode 100644 index 000000000..1ba19a87a --- /dev/null +++ b/app/views/shared/_timeline_friends.html.erb @@ -0,0 +1,16 @@ +
+
+
+ <%= link_to user_path(user.id) do %> + <% if user.profile.prof_photo_id %> + <%= image_tag user.profile_picture.url, id:"timeline-friend-img" %> + <% else %> + + <% end %> + <% end %> +
+
+
<%= link_to user_header_name(user.id), user_path(user) %>
+
+
+
\ No newline at end of file diff --git a/app/views/shared/_timeline_photos.html.erb b/app/views/shared/_timeline_photos.html.erb new file mode 100644 index 000000000..9402d1712 --- /dev/null +++ b/app/views/shared/_timeline_photos.html.erb @@ -0,0 +1,5 @@ +
+ <%= link_to photo_path(user_id: @timeline_user.id, id: photo.id) do %> + <%= image_tag photo.image.url, id:"photo-img" %> + <% end %> +
\ No newline at end of file diff --git a/app/views/shared/_user_index.html.erb b/app/views/shared/_user_index.html.erb new file mode 100644 index 000000000..c71fd1dbf --- /dev/null +++ b/app/views/shared/_user_index.html.erb @@ -0,0 +1,15 @@ +
+
+
+ + + +
<%= link_to user_header_name(user.id), user_path(user) %>
<%= user.friend_count %> Friends
+ <% if current_user.friends.include?(user) %> + <%= link_to "Unfriend me", friending_path(user.id), method: 'delete', class: "btn btn-info", id:"unfriend-button", role:"button" %> + <% elsif current_user.friends.exclude?(user) %> + <%= link_to "Friend me!", friendings_path(friended_id: user.id), method: 'post', class: "btn btn-info", id:"unfriend-button", role:"button" %> + <% end %> +
+
+
\ No newline at end of file diff --git a/app/views/static_pages/about.html.erb b/app/views/static_pages/about.html.erb new file mode 100644 index 000000000..bc50c428d --- /dev/null +++ b/app/views/static_pages/about.html.erb @@ -0,0 +1,98 @@ + +
+
+ +
+ +
+ +
+ +

Harry Potter

+
+
+
+ + <%= render "shared/nav_links" %> + +
+
+ +
+

About

+ <% if params[:id] == current_user.id.to_s %> + Edit your Profile + <% end %> +
+ +
+
+
+

Basic Information

+
+
+

Birthday:

+
+
+

July 31st, 1980

+
+
+
+
+

College:

+
+
+

Hogwarts College

+
+
+
+
+

Hometown:

+
+
+

Godrick's Hollow, England

+
+
+
+
+

Currently Lives:

+
+
+

Godrick's Hollow, England

+
+
+

Contact Information

+
+
+

Email:

+
+
+

harry_potter@hogwarts.edu

+
+
+
+
+

Telephone:

+
+
+

555-123-4567

+
+
+
+
+

Words to Live By

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut

+

About Me

+

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. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
+
+ +
diff --git a/app/views/static_pages/about_edit.html.erb b/app/views/static_pages/about_edit.html.erb new file mode 100644 index 000000000..2980a2059 --- /dev/null +++ b/app/views/static_pages/about_edit.html.erb @@ -0,0 +1,95 @@ + +
+
+ +
+ +
+ +
+ +

Harry Potter

+
+
+
+ + <%= render "shared/nav_links" %> +
+
+ +
+

About

+
+ +
+
+
+

Basic Information

+
+
+

Birthday:

+
+
+

July 31st, 1980

+
+
+
+
+

College:

+
+
+ + +
+
+
+
+

Hometown:

+
+
+ +
+
+
+
+

Currently Lives:

+
+
+ +
+
+

Contact Information

+
+
+

Email:

+
+
+

harry_potter@hogwarts.edu

+
+
+
+
+

Telephone:

+
+
+ +
+
+
+
+

Words to Live By

+ +

About Me

+ +
+
+ +
+ +
+
+
+ +
diff --git a/app/views/static_pages/friends.html.erb b/app/views/static_pages/friends.html.erb new file mode 100644 index 000000000..0b2946105 --- /dev/null +++ b/app/views/static_pages/friends.html.erb @@ -0,0 +1,98 @@ + +
+
+ +
+ +
+ +
+ +

Harry Potter

+
+
+
+ + <%= render "shared/nav_links" %> +
+ + +
+ +
+

Friends

+
+ +
+
+
+
+
+ + + +
Hermoine Granger
432 Friends
+ Unfriend me +
+
+
+
+
+
+ + + +
Hermoine Granger
432 Friends
+ Unfriend me +
+
+
+
+
+
+ + + +
Hermoine Granger
432 Friends
+ Unfriend me +
+
+
+
+
+
+ + + +
Hermoine Granger
432 Friends
+ Unfriend me +
+
+
+
+
+
+ + + +
Hermoine Granger
432 Friends
+ Unfriend me +
+
+
+
+
+
+ + + +
Hermoine Granger
432 Friends
+ Unfriend me +
+
+
+
+
+
+ +
diff --git a/app/views/static_pages/home.html.erb b/app/views/static_pages/home.html.erb new file mode 100644 index 000000000..93a2cdc0b --- /dev/null +++ b/app/views/static_pages/home.html.erb @@ -0,0 +1,76 @@ +
+
+
+
+

Connect with all your friends!

+
+
    +
  • See photos and updates in your news feed.
  • +
  • Post your status for the world to see from your profile
  • +
  • Get in touch with your friends by "friending" them
  • +
  • Like things because you're a positive person!
  • +
+
+
+
+

Sign Up

+
+ + +
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+

Birthday

+
+
+ +
+
+
+
+
+ + + + +
+
+
+
+
+ +
+
+
+ + +
+ +
+
+ diff --git a/app/views/static_pages/photos.html.erb b/app/views/static_pages/photos.html.erb new file mode 100644 index 000000000..1d45b18b1 --- /dev/null +++ b/app/views/static_pages/photos.html.erb @@ -0,0 +1,122 @@ + +
+
+ +
+ +
+ +
+ +

Harry Potter

+
+
+
+ + <%= render "shared/nav_links" %> +
+
+ +
+

Photos

+ Add Photo! +
+ + +
+ +
\ No newline at end of file diff --git a/app/views/static_pages/timeline.html.erb b/app/views/static_pages/timeline.html.erb new file mode 100644 index 000000000..5fbc1739b --- /dev/null +++ b/app/views/static_pages/timeline.html.erb @@ -0,0 +1,284 @@ + + +
+
+ +
+ +
+ +
+ +

Harry Potter

+
+
+
+ + <%= render "shared/nav_links" %> +
+ +
+
+
+
+
+ +
+
About (Text Area)
+
+
+

Born on: July 31st, 1980

+

Went to school at: Hogwarts

+

Hometown: Godrick's Hollow, England

+

Currently Lives: Godrick's Hollow

+
+ +
+
Photos (123) (Copied Text Area)
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+ +
+
+ +
+
Friends (542) (Copied Text Area)
+
+
+
+
+ +
Friend name
+
+
+ +
Friend name
+
+
+ +
Friend name
+
+
+ +
Friend name
+
+
+ +
Friend name
+
+
+ +
Friend name
+
+ +
+
+
+
+ +
+
+
+
+ +
+
Post (copied)
+
+
+ +
+
+ Post! +
+ + + + + + +
+
+
+
+ +
+
+
+ +
diff --git a/app/views/timelines/show.html.erb b/app/views/timelines/show.html.erb new file mode 100644 index 000000000..62157201e --- /dev/null +++ b/app/views/timelines/show.html.erb @@ -0,0 +1,88 @@ + + +
+
+ + <%= render partial: "shared/cover_and_prof", locals: {user: @user} %> + + <%= render "shared/nav_links" %> +
+ +
+
+
+
+
+ +
+
About
+
+
+

Born on: <%= @timeline_user.profile.birthday.strftime("%m/%d/%Y") if @timeline_user.profile.birthday != nil %>

+

Went to school at: <%= @timeline_user.profile.college %>

+

Hometown: <%= @timeline_user.profile.hometown %>

+

Currently Lives: <%= @timeline_user.profile.currently_lives %>

+
+ +
+
<%= "Photos (#{real_user.photos.count})" %>
+
+
+
+ <% real_user.photos[0..5].each do |photo| %> + <%= render partial: "shared/timeline_photos", locals: {photo: photo} %> + <% end %> +
+
<%= link_to "See more photos", photos_path(id: real_user_id)%>
+
+
+
+ +
+
<%= "Friends (#{@timeline_user.friend_count})" %>
+
+
+
+ <% @timeline_user.friends[0..5].each do |friend| %> + <%= render partial: "shared/timeline_friends", locals: {user: friend} %> + <% end %> +
+
<%= link_to "See more friends", user_friends_path(id: real_user_id)%>
+
+
+
+
+
+ +
+
+
+
+ +
+
New Posts
+
+ <%= simple_form_for @post, remote: true do |post_fields| %> +
+ <%= post_fields.input :body, input_html: {rows: "4"}, label: false, placeholder: "Tell the world something..." %> +
+
+ <%= post_fields.submit "Post!", class:"btn btn-primary pull-right", id:"post-submit-button"%> +
+ <% end %> + +
+ <% @timeline_user.posts_received.reverse.each do |post| %> + <%= render partial: "shared/post_box", locals: {post: post} %> + <% end %> +
+
+
+
+
+ +
+
+
+ +
diff --git a/app/views/user_mailer/comment.html.erb b/app/views/user_mailer/comment.html.erb new file mode 100644 index 000000000..05be63925 --- /dev/null +++ b/app/views/user_mailer/comment.html.erb @@ -0,0 +1,6 @@ +

Good news!

+ +

A user with the mail <%= @comment_user.email %> commented on one of your posts or photos. They said: "<%= @comment %>".

+ +

<%= link_to "Click here", user_timeline_url(@owner_user) %> to see more action on your timeline

+ diff --git a/app/views/user_mailer/comment.text.erb b/app/views/user_mailer/comment.text.erb new file mode 100644 index 000000000..9f9ec7875 --- /dev/null +++ b/app/views/user_mailer/comment.text.erb @@ -0,0 +1,5 @@ +Good news! + +A user with the mail <%= @comment_user.email %> commented on one of your posts. They said: <%= @comment %>. + +<%= link_to "Click here", user_timeline_url(@owner_user) %> to see more action on your timeline. \ No newline at end of file diff --git a/app/views/user_mailer/welcome.html.erb b/app/views/user_mailer/welcome.html.erb new file mode 100644 index 000000000..1c0ded67a --- /dev/null +++ b/app/views/user_mailer/welcome.html.erb @@ -0,0 +1,9 @@ +

Welcome!

+ +

+ Hello <%= @user.email %>, welcome to Danebook! +

+ +

+ To view your profile and start making changes, go to <%= link_to "#{user_url(@user.id)}", user_url(@user.id) %> +

\ No newline at end of file diff --git a/app/views/user_mailer/welcome.text.erb b/app/views/user_mailer/welcome.text.erb new file mode 100644 index 000000000..525bf122e --- /dev/null +++ b/app/views/user_mailer/welcome.text.erb @@ -0,0 +1,5 @@ +Welcome! + +Hi <%= @user.email %>, welcome to Danebook! + +To view your profile and start making changes, go to <%= link_to "#{user_url(@user.id)}", user_url(@user.id) %> \ No newline at end of file diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100644 index 000000000..981ca07e3 --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,120 @@ + +
+ <%= simple_form_for @user do |user_fields| %> +
+ +
+ <% if real_user.profile.cover_photo_id %> + <%= image_tag real_user.cover_photo.url, class:"img-responsive" %> + <% else %> + <%= image_tag "cover_photo.jpg", class:"img-responsive" %> + <% end %> + + <%= user_fields.simple_fields_for :profile do |profile_fields| %> +
+ +
+ <% if real_user.profile.prof_photo %> + <%= image_tag real_user.profile_picture.url(:profile) %> + <% else %> + + <% end %> +
+
+ <%= profile_fields.input :first_name, class:"form-control", label: false %> + <%= profile_fields.input :last_name, class:"form-control", label: false %> +
+
+
+ + <%= render "shared/nav_links" %> +
+
+ +
+

About

+
+ + +
+
+
+

Basic Information

+
+
+

Birthday:

+
+
+ <%= profile_fields.input :birthday, as: :date, start_year: Date.today.year - 90, + end_year: Date.today.year - 12, + order: [:day, :month, :year], + class:"form-control", + label: false, + include_blank: true + %> +
+
+
+
+

College:

+
+
+ + <%= profile_fields.input :college, class:"form-control", label: false %> +
+
+
+
+

Hometown:

+
+
+ <%= profile_fields.input :hometown, class:"form-control", label: false %> +
+
+
+
+

Currently Lives:

+
+
+ <%= profile_fields.text_field :currently_lives, class:"form-control" %> +
+
+ <% end %> +

Contact Information

+
+
+

Email:

+
+
+ <%= user_fields.input :email, class:"form-control", label: false %> +
+
+ <%= user_fields.simple_fields_for :profile do |profile_fields| %> +
+
+

Telephone:

+
+
+ <%= profile_fields.input :telephone, class:"form-control", label: false %> +
+
+
+
+

Words to Live By

+ <%= profile_fields.input :words_to_live_by, class:"form-control", label: false, input_html: {rows: "3"} %> +

About Me

+ <%= profile_fields.input :about_me, class:"form-control", label: false, input_html: {rows: "6"} %> +
+
+ <% end %> + +
+
+ <%= user_fields.submit "Save Changes", class:"btn btn-primary btn-lg btn-block", id:"save-changes" %> +
+
+
+ <% end %> +
+ +
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb new file mode 100644 index 000000000..868b0b475 --- /dev/null +++ b/app/views/users/index.html.erb @@ -0,0 +1,19 @@ +
+
+
+ <% if @search_terms == nil %> +

Nearby Friends

+ <% else %> +

Search Results for "<%= @search_terms %>"

+ <% end %> +
+
+
+ <% @users.each do |user| %> + <% next if user == current_user %> + <%= render partial: "shared/friend_page", locals: {user: user} %> + <% end %> +
+
+
+
diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 000000000..a959b8fde --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,84 @@ + +
+
+
+
+

Connect with all your friends!

+
+
    +
  • See photos and updates in your news feed.
  • +
  • Post your status for the world to see from your profile
  • +
  • Get in touch with your friends by "friending" them
  • +
  • Like things because you're a positive person!
  • +
+
+
+
+

Sign Up

+ <%= simple_form_for @user do |user_fields| %> + <%= user_fields.simple_fields_for :profile_attributes do |profile_fields| %> +
+
+ <%= profile_fields.input :first_name, class:"form-control", label: false, placeholder: "First Name" %> +
+
+ <%= profile_fields.input :last_name, class:"form-control", label: false, placeholder: "Last Name" %> +
+
+ <% end %> +
+
+ <%= user_fields.input :email, placeholder: "Your Email", class:"form-control", label: false %> +
+
+
+
+ <%= user_fields.input :password, placeholder: "Your New Password", class:"form-control", label: false %> +
+
+
+
+ <%= user_fields.input :password_confirmation, placeholder: "Confirm Your Password", class:"form-control", label: false %> +
+
+ <%= user_fields.simple_fields_for :profile_attributes do |profile_fields| %> + +

Birthday

+
+
+ <%= profile_fields.input :birthday, as: :date, start_year: Date.today.year - 90, + end_year: Date.today.year - 12, + order: [ :month, :day, :year], + class:"form-control", + label: false, + include_blank: true %> +
+
+
+
+
+ + + + +
+
+
+ <% end %> +
+
+ +
+
+ <% end %> + + +
+ +
+
+ diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100644 index 000000000..65eeed1c9 --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1,83 @@ + +
+
+ + <%= render partial: "shared/cover_and_prof", locals: {user: @user} %> + + <%= render "shared/nav_links" %> + +
+
+ +
+

About

+ <% if params[:id] == current_user.id.to_s %> + <%= link_to "Edit your Profile", edit_user_path(current_user), class: "btn btn-primary", role: "button" %> + <% end %> +
+ +
+
+
+

Basic Information

+
+
+

Birthday:

+
+
+

<%= @user.profile.birthday.strftime("%m/%d/%Y") if real_user.profile.birthday %>

+
+
+
+
+

College:

+
+
+

<%= @user.profile.college %>

+
+
+
+
+

Hometown:

+
+
+

<%= @user.profile.hometown %>

+
+
+
+
+

Currently Lives:

+
+
+

<%= @user.profile.currently_lives %>

+
+
+

Contact Information

+
+
+

Email:

+
+
+

<%= @user.email %>

+
+
+
+
+

Telephone:

+
+
+

<%= @user.profile.telephone %>

+
+
+
+
+

Words to Live By

+

<%= @user.profile.words_to_live_by %>

+

About Me

+

<%= @user.profile.about_me %>

+
+
+
+
+ +
diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 000000000..66e9889e8 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/delayed_job b/bin/delayed_job new file mode 100755 index 000000000..edf195985 --- /dev/null +++ b/bin/delayed_job @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) +require 'delayed/command' +Delayed::Command.new(ARGV).daemonize diff --git a/bin/rails b/bin/rails new file mode 100755 index 000000000..5badb2fde --- /dev/null +++ b/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 000000000..d87d5f578 --- /dev/null +++ b/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 000000000..e620b4dad --- /dev/null +++ b/bin/setup @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:setup' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/bin/spring b/bin/spring new file mode 100755 index 000000000..7fe232c3a --- /dev/null +++ b/bin/spring @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)) + Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq.join(Gem.path_separator) } + gem 'spring', match[1] + require 'spring/binstub' + end +end diff --git a/bin/update b/bin/update new file mode 100755 index 000000000..a8e4462f2 --- /dev/null +++ b/bin/update @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/config.ru b/config.ru new file mode 100644 index 000000000..f7ba0b527 --- /dev/null +++ b/config.ru @@ -0,0 +1,5 @@ +# This file is used by Rack-based servers to start the application. + +require_relative 'config/environment' + +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 000000000..af54ad3ac --- /dev/null +++ b/config/application.rb @@ -0,0 +1,15 @@ +require_relative 'boot' + +require 'rails/all' + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module ProjectDanebook + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 000000000..30f5120df --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..0bbde6f74 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,9 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: redis://localhost:6379/1 diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 000000000..432473cac --- /dev/null +++ b/config/database.yml @@ -0,0 +1,24 @@ +# SQLite version 3.x +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem 'sqlite3' +# +default: &default + adapter: postgresql + pool: 5 + timeout: 5000 + +development: + <<: *default + database: db/development_danebook + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: db/test_danebook +production: + <<: *default + database: db/production_danebook \ No newline at end of file diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 000000000..426333bb4 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative 'application' + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 000000000..764f5c1b7 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,77 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + config.action_mailer.default_url_options = { :host => 'localhost:3000' } + config.action_mailer.delivery_method = :letter_opener + + Paperclip.options[:command_path] = "/usr/local/bin" + + config.paperclip_defaults = { + + # Don't forget to make S3 your storage option! + :storage => :s3, + :s3_credentials => { + + :s3_region => Rails.application.secrets.aws_region, + # put your host name here if needed + # see the reading below for more details + # NOTE: This must be the correct region for YOU + :s3_host_name => "s3.amazonaws.com", + # NOTE: these lines are changed to use secrets.yml + # from the examples (which use ENV vars instead) + :bucket => Rails.application.secrets.s3_bucket_name, + :access_key_id => Rails.application.secrets.aws_access_key_id, + :secret_access_key => Rails.application.secrets.aws_secret_access_key + } + } + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + if Rails.root.join('tmp/caching-dev.txt').exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => 'public, max-age=172800' + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Suppress logger output for asset requests. + config.assets.quiet = true + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true + + # Use an evented file watcher to asynchronously detect changes in source code, + # routes, locales, etc. This feature depends on the listen gem. + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 000000000..827c914e8 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,122 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + config.action_mailer.smtp_settings = { + :address => 'smtp.sendgrid.net', + :port => '587', + :authentication => :plain, + :user_name => ENV['SENDGRID_USERNAME'], + :password => ENV['SENDGRID_PASSWORD'], + :domain => 'heroku.com', + :enable_starttls_auto => true + } + config.action_mailer.delivery_method ||= :smtp + + # Rails also needs to know where your app is + # located to properly configure sending of emails + config.action_mailer.default_url_options = { + :host => 'floating-scrubland-17624.herokuapp.com', + } + + config.paperclip_defaults = { + + # Don't forget to make S3 your storage option! + :storage => :s3, + :s3_credentials => { + + :s3_region => Rails.application.secrets.aws_region, + # put your host name here if needed + # see the reading below for more details + # NOTE: This must be the correct region for YOU + :s3_host_name => "s3.amazonaws.com", + # NOTE: these lines are changed to use secrets.yml + # from the examples (which use ENV vars instead) + :bucket => Rails.application.secrets.s3_bucket_name, + :access_key_id => Rails.application.secrets.aws_access_key_id, + :secret_access_key => Rails.application.secrets.aws_secret_access_key + } + } + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Mount Action Cable outside main process or domain + # config.action_cable.mount_path = nil + # config.action_cable.url = 'wss://example.com/cable' + # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment) + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "project_danebook_#{Rails.env}" + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 000000000..30587ef6d --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,42 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => 'public, max-age=3600' + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100644 index 000000000..51639b67a --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,6 @@ +# Be sure to restart your server when you modify this file. + +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 000000000..01ef3e663 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,11 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = '1.0' + +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. +# Rails.application.config.assets.precompile += %w( search.js ) diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 000000000..59385cdf3 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb new file mode 100644 index 000000000..5a6a32d37 --- /dev/null +++ b/config/initializers/cookies_serializer.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. + +# Specify a serializer for the signed and encrypted cookie jars. +# Valid options are :json, :marshal, and :hybrid. +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 000000000..4a994e1e7 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 000000000..ac033bf9d --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 000000000..dc1899682 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb new file mode 100644 index 000000000..0706cafd4 --- /dev/null +++ b/config/initializers/new_framework_defaults.rb @@ -0,0 +1,24 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.0 upgrade. +# +# Read the Rails 5.0 release notes for more info on each option. + +# Enable per-form CSRF tokens. Previous versions had false. +Rails.application.config.action_controller.per_form_csrf_tokens = true + +# Enable origin-checking CSRF mitigation. Previous versions had false. +Rails.application.config.action_controller.forgery_protection_origin_check = true + +# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. +# Previous versions had false. +ActiveSupport.to_time_preserves_timezone = true + +# Require `belongs_to` associations by default. Previous versions had false. +Rails.application.config.active_record.belongs_to_required_by_default = true + +# Do not halt callback chains when a callback returns false. Previous versions had true. +ActiveSupport.halt_callback_chains_on_return_false = false + +# Configure SSL options to enable HSTS with subdomains. Previous versions had false. +Rails.application.config.ssl_options = { hsts: { subdomains: true } } diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 000000000..f2d118131 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.session_store :cookie_store, key: '_project_danebook_session' diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb new file mode 100644 index 000000000..934487af6 --- /dev/null +++ b/config/initializers/simple_form.rb @@ -0,0 +1,165 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + # Wrappers are used by the form builder to generate a + # complete input. You can remove any component from the + # wrapper, change the order or even add your own to the + # stack. The options given below are used to wrap the + # whole input. + config.wrappers :default, class: :input, + hint_class: :field_with_hint, error_class: :field_with_errors do |b| + ## Extensions enabled by default + # Any of these extensions can be disabled for a + # given input by passing: `f.input EXTENSION_NAME => false`. + # You can make any of these extensions optional by + # renaming `b.use` to `b.optional`. + + # Determines whether to use HTML5 (:email, :url, ...) + # and required attributes + b.use :html5 + + # Calculates placeholders automatically from I18n + # You can also pass a string as f.input placeholder: "Placeholder" + b.use :placeholder + + ## Optional extensions + # They are disabled unless you pass `f.input EXTENSION_NAME => true` + # to the input. If so, they will retrieve the values from the model + # if any exists. If you want to enable any of those + # extensions by default, you can change `b.optional` to `b.use`. + + # Calculates maxlength from length validations for string inputs + b.optional :maxlength + + # Calculates pattern from format validations for string inputs + b.optional :pattern + + # Calculates min and max from length validations for numeric inputs + b.optional :min_max + + # Calculates readonly automatically from readonly attributes + b.optional :readonly + + ## Inputs + b.use :label_input + b.use :hint, wrap_with: { tag: :span, class: :hint } + b.use :error, wrap_with: { tag: :span, class: :error } + + ## full_messages_for + # If you want to display the full error message for the attribute, you can + # use the component :full_error, like: + # + # b.use :full_error, wrap_with: { tag: :span, class: :error } + end + + # The default wrapper to be used by the FormBuilder. + config.default_wrapper = :default + + # Define the way to render check boxes / radio buttons with labels. + # Defaults to :nested for bootstrap config. + # inline: input + label + # nested: label > input + config.boolean_style = :nested + + # Default class for buttons + config.button_class = 'btn' + + # Method used to tidy up errors. Specify any Rails Array method. + # :first lists the first message for each field. + # Use :to_sentence to list all errors for each field. + # config.error_method = :first + + # Default tag used for error notification helper. + config.error_notification_tag = :div + + # CSS class to add for error notification helper. + config.error_notification_class = 'error_notification' + + # ID to add for error notification helper. + # config.error_notification_id = nil + + # Series of attempts to detect a default label method for collection. + # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] + + # Series of attempts to detect a default value method for collection. + # config.collection_value_methods = [ :id, :to_s ] + + # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. + # config.collection_wrapper_tag = nil + + # You can define the class to use on all collection wrappers. Defaulting to none. + # config.collection_wrapper_class = nil + + # You can wrap each item in a collection of radio/check boxes with a tag, + # defaulting to :span. + # config.item_wrapper_tag = :span + + # You can define a class to use in all item wrappers. Defaulting to none. + # config.item_wrapper_class = nil + + # How the label text should be generated altogether with the required text. + # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" } + + # You can define the class to use on all labels. Default is nil. + # config.label_class = nil + + # You can define the default class to be used on forms. Can be overriden + # with `html: { :class }`. Defaulting to none. + # config.default_form_class = nil + + # You can define which elements should obtain additional classes + # config.generate_additional_classes_for = [:wrapper, :label, :input] + + # Whether attributes are required by default (or not). Default is true. + # config.required_by_default = true + + # Tell browsers whether to use the native HTML5 validations (novalidate form option). + # These validations are enabled in SimpleForm's internal config but disabled by default + # in this configuration, which is recommended due to some quirks from different browsers. + # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations, + # change this configuration to true. + config.browser_validations = false + + # Collection of methods to detect if a file type was given. + # config.file_methods = [ :mounted_as, :file?, :public_filename ] + + # Custom mappings for input types. This should be a hash containing a regexp + # to match as key, and the input type that will be used when the field name + # matches the regexp as value. + # config.input_mappings = { /count/ => :integer } + + # Custom wrappers for input types. This should be a hash containing an input + # type as key and the wrapper that will be used for all inputs with specified type. + # config.wrapper_mappings = { string: :prepend } + + # Namespaces where SimpleForm should look for custom input classes that + # override default inputs. + # config.custom_inputs_namespaces << "CustomInputs" + + # Default priority for time_zone inputs. + # config.time_zone_priority = nil + + # Default priority for country inputs. + # config.country_priority = nil + + # When false, do not use translations for labels. + # config.translate_labels = true + + # Automatically discover new inputs in Rails' autoload path. + # config.inputs_discovery = true + + # Cache SimpleForm inputs discovery + # config.cache_discovery = !Rails.env.development? + + # Default class for inputs + # config.input_class = nil + + # Define the default class of the input wrapper of the boolean input. + config.boolean_label_class = 'checkbox' + + # Defines if the default input wrapper class should be included in radio + # collection wrappers. + # config.include_default_input_wrapper_class = true + + # Defines which i18n scope will be used in Simple Form. + # config.i18n_scope = 'simple_form' +end diff --git a/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb new file mode 100644 index 000000000..109d29a37 --- /dev/null +++ b/config/initializers/simple_form_bootstrap.rb @@ -0,0 +1,149 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + config.error_notification_class = 'alert alert-danger' + config.button_class = 'btn btn-default' + config.boolean_label_class = nil + + config.wrappers :vertical_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.use :placeholder + b.optional :maxlength + b.optional :pattern + b.optional :min_max + b.optional :readonly + b.use :label, class: 'control-label' + + b.use :input, class: 'form-control' + b.use :error, wrap_with: { tag: 'span', class: 'help-block' } + b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + + config.wrappers :vertical_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.use :placeholder + b.optional :maxlength + b.optional :readonly + b.use :label, class: 'control-label' + + b.use :input + b.use :error, wrap_with: { tag: 'span', class: 'help-block' } + b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + + config.wrappers :vertical_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.optional :readonly + + b.wrapper tag: 'div', class: 'checkbox' do |ba| + ba.use :label_input + end + + b.use :error, wrap_with: { tag: 'span', class: 'help-block' } + b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + + config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.optional :readonly + b.use :label, class: 'control-label' + b.use :input + b.use :error, wrap_with: { tag: 'span', class: 'help-block' } + b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + + config.wrappers :horizontal_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.use :placeholder + b.optional :maxlength + b.optional :pattern + b.optional :min_max + b.optional :readonly + b.use :label, class: 'col-sm-3 control-label' + + b.wrapper tag: 'div', class: 'col-sm-9' do |ba| + ba.use :input, class: 'form-control' + ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } + ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + end + + config.wrappers :horizontal_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.use :placeholder + b.optional :maxlength + b.optional :readonly + b.use :label, class: 'col-sm-3 control-label' + + b.wrapper tag: 'div', class: 'col-sm-9' do |ba| + ba.use :input + ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } + ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + end + + config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.optional :readonly + + b.wrapper tag: 'div', class: 'col-sm-offset-3 col-sm-9' do |wr| + wr.wrapper tag: 'div', class: 'checkbox' do |ba| + ba.use :label_input + end + + wr.use :error, wrap_with: { tag: 'span', class: 'help-block' } + wr.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + end + + config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.optional :readonly + + b.use :label, class: 'col-sm-3 control-label' + + b.wrapper tag: 'div', class: 'col-sm-9' do |ba| + ba.use :input + ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } + ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + end + + config.wrappers :inline_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.use :placeholder + b.optional :maxlength + b.optional :pattern + b.optional :min_max + b.optional :readonly + b.use :label, class: 'sr-only' + + b.use :input, class: 'form-control' + b.use :error, wrap_with: { tag: 'span', class: 'help-block' } + b.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + + config.wrappers :multi_select, tag: 'div', class: 'form-group', error_class: 'has-error' do |b| + b.use :html5 + b.optional :readonly + b.use :label, class: 'control-label' + b.wrapper tag: 'div', class: 'form-inline' do |ba| + ba.use :input, class: 'form-control' + ba.use :error, wrap_with: { tag: 'span', class: 'help-block' } + ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } + end + end + # Wrappers for forms and inputs using the Bootstrap toolkit. + # Check the Bootstrap docs (http://getbootstrap.com) + # to learn about the different styles for forms and inputs, + # buttons and other elements. + config.default_wrapper = :vertical_form + config.wrapper_mappings = { + check_boxes: :vertical_radio_and_checkboxes, + radio_buttons: :vertical_radio_and_checkboxes, + file: :vertical_file_input, + boolean: :vertical_boolean, + datetime: :multi_select, + date: :multi_select, + time: :multi_select + } +end diff --git a/config/initializers/validates_timeliness.rb b/config/initializers/validates_timeliness.rb new file mode 100644 index 000000000..9f004af77 --- /dev/null +++ b/config/initializers/validates_timeliness.rb @@ -0,0 +1,40 @@ +ValidatesTimeliness.setup do |config| + # Extend ORM/ODMs for full support (:active_record included). + config.extend_orms = [ :active_record ] + # + # Default timezone + # config.default_timezone = :utc + # + # Set the dummy date part for a time type values. + # config.dummy_date_for_time_type = [ 2000, 1, 1 ] + # + # Ignore errors when restriction options are evaluated + # config.ignore_restriction_errors = false + # + # Re-display invalid values in date/time selects + # config.enable_date_time_select_extension! + # + # Handle multiparameter date/time values strictly + # config.enable_multiparameter_extension! + # + # Shorthand date and time symbols for restrictions + # config.restriction_shorthand_symbols.update( + # :now => lambda { Time.current }, + # :today => lambda { Date.current } + # ) + # + # Use the plugin date/time parser which is stricter and extendable + # config.use_plugin_parser = false + # + # Add one or more formats making them valid. e.g. add_formats(:date, 'd(st|rd|th) of mmm, yyyy') + # config.parser.add_formats() + # + # Remove one or more formats making them invalid. e.g. remove_formats(:date, 'dd/mm/yyy') + # config.parser.remove_formats() + # + # Change the ambiguous year threshold when parsing a 2 digit year + # config.parser.ambiguous_year_threshold = 30 + # + # Treat ambiguous dates, such as 01/02/1950, as a Non-US date. + # config.parser.remove_us_formats +end diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 000000000..bbfc3961b --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 000000000..065395716 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,23 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml new file mode 100644 index 000000000..237438334 --- /dev/null +++ b/config/locales/simple_form.en.yml @@ -0,0 +1,31 @@ +en: + simple_form: + "yes": 'Yes' + "no": 'No' + required: + text: 'required' + mark: '*' + # You can uncomment the line below if you need to overwrite the whole required html. + # When using html, text and mark won't be used. + # html: '*' + error_notification: + default_message: "Please review the problems below:" + # Examples + # labels: + # defaults: + # password: 'Password' + # user: + # new: + # email: 'E-mail to sign in.' + # edit: + # email: 'E-mail.' + # hints: + # defaults: + # username: 'User name to sign in.' + # password: 'No special characters, please.' + # include_blanks: + # defaults: + # age: 'Rather not say' + # prompts: + # defaults: + # age: 'Select your age' diff --git a/config/locales/validates_timeliness.en.yml b/config/locales/validates_timeliness.en.yml new file mode 100644 index 000000000..634c9dad9 --- /dev/null +++ b/config/locales/validates_timeliness.en.yml @@ -0,0 +1,16 @@ +en: + errors: + messages: + invalid_date: "is not a valid date" + invalid_time: "is not a valid time" + invalid_datetime: "is not a valid datetime" + is_at: "must be at %{restriction}" + before: "must be before %{restriction}" + on_or_before: "must be on or before %{restriction}" + after: "must be after %{restriction}" + on_or_after: "must be on or after %{restriction}" + validates_timeliness: + error_value_formats: + date: '%Y-%m-%d' + time: '%H:%M:%S' + datetime: '%Y-%m-%d %H:%M:%S' diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 000000000..c7f311f81 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,47 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum, this matches the default thread size of Active Record. +# +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests, default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked webserver processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. If you use this option +# you need to make sure to reconnect any threads in the `on_worker_boot` +# block. +# +# preload_app! + +# The code in the `on_worker_boot` will be called if you are using +# clustered mode by specifying a number of `workers`. After each worker +# process is booted this block will be run, if you are using `preload_app!` +# option you will want to use this block to reconnect to any threads +# or connections that may have been created at application boot, Ruby +# cannot share connections between processes. +# +# on_worker_boot do +# ActiveRecord::Base.establish_connection if defined?(ActiveRecord) +# end + +# Allow puma to be restarted by `rails restart` command. +plugin :tmp_restart diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 000000000..9a1571484 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,23 @@ +Rails.application.routes.draw do + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + root to: "users#new" + + resources :newsfeed, only: [:index] + resources :users do + resource :timeline, only: [:show] + resources :friends, only: [:index] + end + + resources :photos + + resources :likes, only: [:create, :destroy] + resources :posts, only: [:create, :destroy] + + resources :comments, only: [:create, :destroy] + + resource :session, only: [ :new, :create, :destroy ] + resources :friendings, only: [:create, :destroy] + + + +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 000000000..550cd8f76 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,30 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rails secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: 4ebb6e1897a1037e0dc4944961683f20a6f876adb2c37f689a4708e35c60bf5fb6ab1262da8527c1a29d3c47a3dfe7c10129ea6e588a0557f9de25152e78172c + s3_bucket_name: <%= ENV["S3_BUCKET_NAME"] %> + aws_access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %> + aws_secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %> + aws_region: <%= ENV["AWS_REGION"] %> + +test: + secret_key_base: c2ef1b1ac15902cd9686afe5283407c596269ba0a15258a35f83abf6f51d547c13063f8ca98dc060b1959ec5f79385cb946baacc1693ddf25da5970e036be497 + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> + s3_bucket_name: <%= ENV["S3_BUCKET_NAME"] %> + aws_access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %> + aws_secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %> + aws_region: <%= ENV["AWS_REGION"] %> diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 000000000..c9119b40c --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w( + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +).each { |path| Spring.watch(path) } diff --git a/db/migrate/20160810194442_create_users.rb b/db/migrate/20160810194442_create_users.rb new file mode 100644 index 000000000..80aa94660 --- /dev/null +++ b/db/migrate/20160810194442_create_users.rb @@ -0,0 +1,9 @@ +class CreateUsers < ActiveRecord::Migration[5.0] + def change + create_table :users do |t| + t.string :email + t.string :password_digest + t.timestamps + end + end +end diff --git a/db/migrate/20160810222144_add_auth_token_to_users.rb b/db/migrate/20160810222144_add_auth_token_to_users.rb new file mode 100644 index 000000000..350799bed --- /dev/null +++ b/db/migrate/20160810222144_add_auth_token_to_users.rb @@ -0,0 +1,6 @@ +class AddAuthTokenToUsers < ActiveRecord::Migration[5.0] + def change + add_column :users, :auth_token, :string + add_index :users, :auth_token, :unique => true + end +end diff --git a/db/migrate/20160810230233_create_profiles.rb b/db/migrate/20160810230233_create_profiles.rb new file mode 100644 index 000000000..379666638 --- /dev/null +++ b/db/migrate/20160810230233_create_profiles.rb @@ -0,0 +1,13 @@ +class CreateProfiles < ActiveRecord::Migration[5.0] + def change + create_table :profiles do |t| + t.string :first_name + t.string :last_name + t.date :birthday + t.string :gender + t.references :user + + t.timestamps + end + end +end diff --git a/db/migrate/20160810234955_add_columns_to_profile.rb b/db/migrate/20160810234955_add_columns_to_profile.rb new file mode 100644 index 000000000..67ab09579 --- /dev/null +++ b/db/migrate/20160810234955_add_columns_to_profile.rb @@ -0,0 +1,10 @@ +class AddColumnsToProfile < ActiveRecord::Migration[5.0] + def change + add_column :profiles, :college, :string + add_column :profiles, :hometown, :string + add_column :profiles, :currently_lives, :string + add_column :profiles, :telephone, :string + add_column :profiles, :words_to_live_by, :text + add_column :profiles, :about_me, :text + end +end diff --git a/db/migrate/20160811221423_add_uniqueness_to_email.rb b/db/migrate/20160811221423_add_uniqueness_to_email.rb new file mode 100644 index 000000000..726fda392 --- /dev/null +++ b/db/migrate/20160811221423_add_uniqueness_to_email.rb @@ -0,0 +1,5 @@ +class AddUniquenessToEmail < ActiveRecord::Migration[5.0] + def change + add_index :users, :email, :unique => true + end +end diff --git a/db/migrate/20160812182318_create_posts.rb b/db/migrate/20160812182318_create_posts.rb new file mode 100644 index 000000000..c19cbca6d --- /dev/null +++ b/db/migrate/20160812182318_create_posts.rb @@ -0,0 +1,13 @@ +class CreatePosts < ActiveRecord::Migration[5.0] + def change + create_table :posts do |t| + t.integer :post_author_id + t.integer :post_receiver_id + t.integer :postable_id + t.string :postable_type + t.timestamps + end + + add_index :posts, [:postable_id, :postable_type] + end +end diff --git a/db/migrate/20160812182343_create_post_texts.rb b/db/migrate/20160812182343_create_post_texts.rb new file mode 100644 index 000000000..7b1d610a8 --- /dev/null +++ b/db/migrate/20160812182343_create_post_texts.rb @@ -0,0 +1,9 @@ +class CreatePostTexts < ActiveRecord::Migration[5.0] + def change + create_table :post_texts do |t| + t.integer :post_id + t.text :body + t.timestamps + end + end +end diff --git a/db/migrate/20160812182352_create_photos.rb b/db/migrate/20160812182352_create_photos.rb new file mode 100644 index 000000000..9198c9e74 --- /dev/null +++ b/db/migrate/20160812182352_create_photos.rb @@ -0,0 +1,9 @@ +class CreatePhotos < ActiveRecord::Migration[5.0] + def change + create_table :photos do |t| + t.integer :post_id + t.string :image_url + t.timestamps + end + end +end diff --git a/db/migrate/20160812182401_create_videos.rb b/db/migrate/20160812182401_create_videos.rb new file mode 100644 index 000000000..ee2c1d883 --- /dev/null +++ b/db/migrate/20160812182401_create_videos.rb @@ -0,0 +1,9 @@ +class CreateVideos < ActiveRecord::Migration[5.0] + def change + create_table :videos do |t| + t.integer :post_id + t.string :image_url + t.timestamps + end + end +end diff --git a/db/migrate/20160812182408_create_comments.rb b/db/migrate/20160812182408_create_comments.rb new file mode 100644 index 000000000..760d23365 --- /dev/null +++ b/db/migrate/20160812182408_create_comments.rb @@ -0,0 +1,12 @@ +class CreateComments < ActiveRecord::Migration[5.0] + def change + create_table :comments do |t| + t.integer :user_id + t.text :body + t.integer :commentable_id + t.string :commentable_type + t.timestamps + end + + end +end diff --git a/db/migrate/20160812182415_create_likes.rb b/db/migrate/20160812182415_create_likes.rb new file mode 100644 index 000000000..69854053b --- /dev/null +++ b/db/migrate/20160812182415_create_likes.rb @@ -0,0 +1,12 @@ +class CreateLikes < ActiveRecord::Migration[5.0] + def change + create_table :likes do |t| + t.integer :user_id + t.integer :likeable_id + t.string :likeable_type + t.timestamps + end + + add_index :likes, [:likeable_id, :likeable_type] + end +end diff --git a/db/migrate/20160812193629_add_body_to_post.rb b/db/migrate/20160812193629_add_body_to_post.rb new file mode 100644 index 000000000..740768a92 --- /dev/null +++ b/db/migrate/20160812193629_add_body_to_post.rb @@ -0,0 +1,5 @@ +class AddBodyToPost < ActiveRecord::Migration[5.0] + def change + add_column :posts, :body, :text + end +end diff --git a/db/migrate/20160818210702_create_friendings.rb b/db/migrate/20160818210702_create_friendings.rb new file mode 100644 index 000000000..12c3d96c4 --- /dev/null +++ b/db/migrate/20160818210702_create_friendings.rb @@ -0,0 +1,11 @@ +class CreateFriendings < ActiveRecord::Migration[5.0] + def change + create_table :friendings do |t| + t.integer :friended_id, :null => false + t.integer :friender_id, :null => false + + t.timestamps + end + add_index :friendings, [:friended_id, :friender_id], :unique => true + end +end diff --git a/db/migrate/20160818232019_add_profile_pictures_to_profiles.rb b/db/migrate/20160818232019_add_profile_pictures_to_profiles.rb new file mode 100644 index 000000000..451655ccb --- /dev/null +++ b/db/migrate/20160818232019_add_profile_pictures_to_profiles.rb @@ -0,0 +1,6 @@ +class AddProfilePicturesToProfiles < ActiveRecord::Migration[5.0] + def change + add_column :profiles, :prof_photo_id, :integer + add_column :profiles, :cover_photo_id, :integer + end +end diff --git a/db/migrate/20160818235131_add_image_to_photos.rb b/db/migrate/20160818235131_add_image_to_photos.rb new file mode 100644 index 000000000..cb9e0b09d --- /dev/null +++ b/db/migrate/20160818235131_add_image_to_photos.rb @@ -0,0 +1,5 @@ +class AddImageToPhotos < ActiveRecord::Migration[5.0] + def change + add_attachment :photos, :image + end +end diff --git a/db/migrate/20160818235957_add_users_to_photos.rb b/db/migrate/20160818235957_add_users_to_photos.rb new file mode 100644 index 000000000..08cd48f56 --- /dev/null +++ b/db/migrate/20160818235957_add_users_to_photos.rb @@ -0,0 +1,5 @@ +class AddUsersToPhotos < ActiveRecord::Migration[5.0] + def change + add_column :photos, :user_id, :integer + end +end diff --git a/db/migrate/20160819171831_create_delayed_jobs.rb b/db/migrate/20160819171831_create_delayed_jobs.rb new file mode 100644 index 000000000..27fdcf6cc --- /dev/null +++ b/db/migrate/20160819171831_create_delayed_jobs.rb @@ -0,0 +1,22 @@ +class CreateDelayedJobs < ActiveRecord::Migration + def self.up + create_table :delayed_jobs, force: true do |table| + table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue + table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. + table.text :handler, null: false # YAML-encoded string of the object that will do work + table.text :last_error # reason for last failure (See Note below) + table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. + table.datetime :locked_at # Set when a client is working on this object + table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) + table.string :locked_by # Who is working on this object (if locked) + table.string :queue # The name of the queue this job is in + table.timestamps null: true + end + + add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" + end + + def self.down + drop_table :delayed_jobs + end +end diff --git a/db/migrate/20160901212605_edit_index_on_likes.rb b/db/migrate/20160901212605_edit_index_on_likes.rb new file mode 100644 index 000000000..11503bc85 --- /dev/null +++ b/db/migrate/20160901212605_edit_index_on_likes.rb @@ -0,0 +1,5 @@ +class EditIndexOnLikes < ActiveRecord::Migration[5.0] + def change + add_index :likes, [:likeable_id, :likeable_type, :user_id], unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..4c993c48d --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,126 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20160901212605) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "comments", force: :cascade do |t| + t.integer "user_id" + t.text "body" + t.integer "commentable_id" + t.string "commentable_type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "delayed_jobs", force: :cascade do |t| + t.integer "priority", default: 0, null: false + t.integer "attempts", default: 0, null: false + t.text "handler", null: false + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree + end + + create_table "friendings", force: :cascade do |t| + t.integer "friended_id", null: false + t.integer "friender_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["friended_id", "friender_id"], name: "index_friendings_on_friended_id_and_friender_id", unique: true, using: :btree + end + + create_table "likes", force: :cascade do |t| + t.integer "user_id" + t.integer "likeable_id" + t.string "likeable_type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["likeable_id", "likeable_type", "user_id"], name: "index_likes_on_likeable_id_and_likeable_type_and_user_id", unique: true, using: :btree + t.index ["likeable_id", "likeable_type"], name: "index_likes_on_likeable_id_and_likeable_type", using: :btree + end + + create_table "photos", force: :cascade do |t| + t.integer "post_id" + t.string "image_url" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "image_file_name" + t.string "image_content_type" + t.integer "image_file_size" + t.datetime "image_updated_at" + t.integer "user_id" + end + + create_table "post_texts", force: :cascade do |t| + t.integer "post_id" + t.text "body" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "posts", force: :cascade do |t| + t.integer "post_author_id" + t.integer "post_receiver_id" + t.integer "postable_id" + t.string "postable_type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "body" + t.index ["postable_id", "postable_type"], name: "index_posts_on_postable_id_and_postable_type", using: :btree + end + + create_table "profiles", force: :cascade do |t| + t.string "first_name" + t.string "last_name" + t.date "birthday" + t.string "gender" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "college" + t.string "hometown" + t.string "currently_lives" + t.string "telephone" + t.text "words_to_live_by" + t.text "about_me" + t.integer "prof_photo_id" + t.integer "cover_photo_id" + t.index ["user_id"], name: "index_profiles_on_user_id", using: :btree + end + + create_table "users", force: :cascade do |t| + t.string "email" + t.string "password_digest" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "auth_token" + t.index ["auth_token"], name: "index_users_on_auth_token", unique: true, using: :btree + t.index ["email"], name: "index_users_on_email", unique: true, using: :btree + end + + create_table "videos", force: :cascade do |t| + t.integer "post_id" + t.string "image_url" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 000000000..1beea2acc --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). +# +# Examples: +# +# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) +# Character.create(name: 'Luke', movie: movies.first) diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/lib/tasks/timeline_posts.html b/lib/tasks/timeline_posts.html new file mode 100644 index 000000000..26429a9af --- /dev/null +++ b/lib/tasks/timeline_posts.html @@ -0,0 +1,150 @@ + + + + + \ No newline at end of file diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb new file mode 100644 index 000000000..201a069e2 --- /dev/null +++ b/lib/templates/erb/scaffold/_form.html.erb @@ -0,0 +1,13 @@ +<%%= simple_form_for(@<%= singular_table_name %>) do |f| %> + <%%= f.error_notification %> + +
+ <%- attributes.each do |attribute| -%> + <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %> + <%- end -%> +
+ +
+ <%%= f.button :submit %> +
+<%% end %> diff --git a/log/.keep b/log/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/public/404.html b/public/404.html new file mode 100644 index 000000000..0ac77b9ef --- /dev/null +++ b/public/404.html @@ -0,0 +1,68 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

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

+ <%= link_to "Click here to return to your timeline" +
+

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

+
+ + diff --git a/public/422.html b/public/422.html new file mode 100644 index 000000000..a21f82b3b --- /dev/null +++ b/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

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

+
+

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

+
+ + diff --git a/public/500.html b/public/500.html new file mode 100644 index 000000000..061abc587 --- /dev/null +++ b/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

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

+
+ + diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png new file mode 100644 index 000000000..e69de29bb diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 000000000..e69de29bb diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 000000000..e69de29bb diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 000000000..3c9c7c01f --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/spec/controllers/friendings_controller_spec.rb b/spec/controllers/friendings_controller_spec.rb new file mode 100644 index 000000000..55d19a900 --- /dev/null +++ b/spec/controllers/friendings_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe FriendingsController, type: :controller do + +end diff --git a/spec/controllers/newsfeed_controller_spec.rb b/spec/controllers/newsfeed_controller_spec.rb new file mode 100644 index 000000000..b133afb23 --- /dev/null +++ b/spec/controllers/newsfeed_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe NewsfeedController, type: :controller do + +end diff --git a/spec/controllers/sessions_controllers_spec.rb b/spec/controllers/sessions_controllers_spec.rb new file mode 100644 index 000000000..a6064d90d --- /dev/null +++ b/spec/controllers/sessions_controllers_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +describe SessionsController do + + let(:user){create(:user)} + + describe "POST #create" do + + describe "valid log in" do + + it "valid credentials create a new log in" do + expect{ post :create, email: "foobar@foo.com", password: "foobar" }.to change(Session, :count).by(1) + end + + end + + end + +end \ No newline at end of file diff --git a/spec/controllers/timelines_controllers_spec.rb b/spec/controllers/timelines_controllers_spec.rb new file mode 100644 index 000000000..51c9a587a --- /dev/null +++ b/spec/controllers/timelines_controllers_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +describe TimelinesController do + let(:profile) {create(:profile)} + let(:user){ create(:user, :profile => profile )} + + before do + login(user) + end + + describe "GET #show" do + + it "gets the right user's timeline" do + get :show, params: {user_id: user.id} + expect(response.status).to eq(200) + end + + end + +end \ No newline at end of file diff --git a/spec/controllers/users_controllers_spec.rb b/spec/controllers/users_controllers_spec.rb new file mode 100644 index 000000000..f6122c5fc --- /dev/null +++ b/spec/controllers/users_controllers_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe UsersController do + + let(:user) {create(:user)} + + describe "POST #create" do + + context "valid user" do + it "properly creates user" do + expect{ post :create, user: attributes_for(:user) }.to change(User, :count).by(1) + end + end + + context "invalid user" do + it "throws an error" do + expect { post :create, user: attributes_for(:user, password: "") }.to change(User, :count).by(0) + expect(response).to render_template :new + end + end + end + + + +end \ No newline at end of file diff --git a/spec/factories.rb b/spec/factories.rb new file mode 100644 index 000000000..615bb740e --- /dev/null +++ b/spec/factories.rb @@ -0,0 +1,51 @@ +FactoryGirl.define do + factory :friending do + + end + + factory :user do + email "foobar@foo.com" + password "foobar" + password_confirmation "foobar" + end + + factory :post do + post_receiver_id 1 + body "Post body" + end + + factory :like do + likeable_id 1 + factory :comment_like do + likeable_type "Comment" + end + factory :post_like do + likeable_type "Post" + end + end + + factory :profile do + first_name "Foo" + last_name "Bar" + college "Baz State" + hometown "Boston" + currently_lives "Boston" + words_to_live_by "hello hello hello" + about_me "goodbye goodbye goodbye" + telephone "1234567890" + end + + factory :comment do + body "Test comment" + commentable_id 1 + commentable_type "Post" + end + + + + + + + + +end \ No newline at end of file diff --git a/spec/features/friendings_spec.rb b/spec/features/friendings_spec.rb new file mode 100644 index 000000000..30ae615dc --- /dev/null +++ b/spec/features/friendings_spec.rb @@ -0,0 +1,34 @@ +require 'rails_helper' + +feature 'Friending' do + + let(:profile) {create(:profile)} + let(:other_profile) {create(:profile)} + let(:user){ create(:user, profile: profile)} + let(:other_user){ create(:user, :email => "foo2@email.com", profile: profile)} + + before do + visit root_path + sign_in(user) + visit user_path(other_user.id) + end + + scenario "'friend' button appears for users who are not friends with current user'" do + expect(page).to have_content("Friend #{other_profile.first_name}") + end + + + scenario "'unfriend' button appears for users who are friends with current user'" do + click_link("Friend #{other_profile.first_name}") + expect(page).to have_content("Unfriend #{other_profile.first_name}") + end + + + + + + + + + +end \ No newline at end of file diff --git a/spec/features/likes_spec.rb b/spec/features/likes_spec.rb new file mode 100644 index 000000000..e69de29bb diff --git a/spec/features/posts_spec.rb b/spec/features/posts_spec.rb new file mode 100644 index 000000000..a618302d1 --- /dev/null +++ b/spec/features/posts_spec.rb @@ -0,0 +1,62 @@ +require 'rails_helper' + +feature 'Creating New Post' do + + let(:profile) {create(:profile)} + let(:other_profile) {create(:profile)} + let(:user){ create(:user, profile: profile)} + let(:other_user){ create(:user, :email => "foo2@email.com", profile: profile)} + + before do + visit root_path + sign_in(user) + end + + scenario "creating a post" do + fill_in "post[body]", with: "Post body" + expect{ click_button "Post!" }.to change(Post, :count).by(1) + expect(page).to have_css(".alert-success") + + end + + scenario "can't create an empty post" do + + fill_in "post[body]", with: "" + expect{ click_button "Post!" }.to change(Post, :count).by(0) + expect(page).to have_css(".alert-danger") + + end + + scenario "deleting a post you wrote" do + + fill_in "post[body]", with: "Post body" + click_button "Post!" + expect{ click_link "Delete Post"}.to change(Post, :count).by(-1) + expect(page).to have_css(".alert-success") + + end + + + + +end + + + + + + + + + + + + + + + + + + + + diff --git a/spec/features/profiles_spec.rb b/spec/features/profiles_spec.rb new file mode 100644 index 000000000..1f9c6d125 --- /dev/null +++ b/spec/features/profiles_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +feature 'Editing Profile' do + + before do + visit root_path + end + + let(:profile) {create(:profile)} + let(:user){ create(:user, :profile => profile )} + + scenario "editing a profile with valid params succeeds" do + sign_in(user) + click_link("Edit Profile") + fill_in "user[profile_attributes][college]", with: "Harvard" + fill_in "user[profile_attributes][hometown]", with: "Harvard" + fill_in "user[profile_attributes][currently_lives]", with: "Harvard" + click_button("Save Changes") + expect(page).to have_css(".alert-success") + end + + scenario "editing a profile with invalid params fails" do + sign_in(user) + click_link("Edit Profile") + fill_in "user[profile_attributes][telephone]", with: "111" + click_button("Save Changes") + expect(page).to have_css(".alert-danger") + end + + + + +end \ No newline at end of file diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb new file mode 100644 index 000000000..0e8a62432 --- /dev/null +++ b/spec/features/users_spec.rb @@ -0,0 +1,53 @@ +require 'rails_helper' + +feature 'Signing Up' do + + before do + visit root_path + end + + scenario "adds a new user" do + sign_up("foo@bar.com") + expect{ click_button "Sign Up!" }.to change(User, :count).by(1) + expect(page).to have_css(".alert-success") + end + + scenario "user can't be created with same email address" do + sign_up("foo@bar.com") + click_button("Sign Up!") + click_link("Logout") + sign_up("foo@bar.com") + click_button("Sign Up!") + expect(page).to have_css(".alert-danger") + expect(page).to have_content "has already been taken" + end + +end + +feature 'Logging in and out' do + + let(:profile) {create(:profile)} + let(:user){ create(:user, :profile => profile )} + before do + user + visit root_path + end + + scenario "user can log in with valid credentials" do + sign_in(user) + expect(page).to have_css(".alert-success") + end + + + scenario "user can log out" do + sign_up("foo@bar.com") + click_button("Sign Up!") + click_link("Logout") + expect(page).to have_css(".alert-success") + end + + + + + +end \ No newline at end of file diff --git a/spec/helpers/friendings_helper_spec.rb b/spec/helpers/friendings_helper_spec.rb new file mode 100644 index 000000000..e8a5977d7 --- /dev/null +++ b/spec/helpers/friendings_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the FriendingsHelper. For example: +# +# describe FriendingsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe FriendingsHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/helpers/newsfeed_helper_spec.rb b/spec/helpers/newsfeed_helper_spec.rb new file mode 100644 index 000000000..bdc7c6848 --- /dev/null +++ b/spec/helpers/newsfeed_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the NewsfeedHelper. For example: +# +# describe NewsfeedHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe NewsfeedHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb new file mode 100644 index 000000000..957e12b64 --- /dev/null +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -0,0 +1,4 @@ +# Preview all emails at http://localhost:3000/rails/mailers/user_mailer +class UserMailerPreview < ActionMailer::Preview + +end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb new file mode 100644 index 000000000..c48d3adee --- /dev/null +++ b/spec/mailers/user_mailer_spec.rb @@ -0,0 +1,5 @@ +require "rails_helper" + +RSpec.describe UserMailerMailer, type: :mailer do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb new file mode 100644 index 000000000..f38b6dd23 --- /dev/null +++ b/spec/models/comment_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +describe Comment do + + let(:user){create(:user)} + let(:post){user.posts_written.create(attributes_for(:post))} + let(:comment){user.comments_written.build(attributes_for(:comment, commentable_id: post.id) )} + + it "should be valid with valid attributes" do + expect(comment).to be_valid + end + + it { should belong_to(:user)} + + it { should belong_to(:commentable)} + + it { should have_many(:comments)} + + it { should have_many(:likes)} + + + + +end \ No newline at end of file diff --git a/spec/models/friending_spec.rb b/spec/models/friending_spec.rb new file mode 100644 index 000000000..e5b208edf --- /dev/null +++ b/spec/models/friending_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Friending, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/like_spec.rb b/spec/models/like_spec.rb new file mode 100644 index 000000000..6e356462b --- /dev/null +++ b/spec/models/like_spec.rb @@ -0,0 +1,35 @@ +require 'rails_helper' + +describe Like do + + let(:user){create(:user)} + let(:post){user.posts_written.create(attributes_for(:post))} + let(:comment){user.comments_written.create(attributes_for(:comment, commentable_id: post.id) )} + let(:comment_like){user.likes_given.create(attributes_for(:comment_like, likeable_id: comment.id))} + let(:post_like){user.likes_given.create(attributes_for(:post_like, likeable_id: post.id))} + + it "should be valid with valid attributes" do + expect(comment_like).to be_valid + end + + it "should be valid with valid attributes" do + expect(post_like).to be_valid + end + + it {should belong_to(:user)} + + it { should belong_to(:likeable)} + + it "should find the correct path for its type" do + expect(Like.find_likable_type("/comments/1/like")).to eq("Comment") + expect(Like.find_likable_type("/posts/1/like")).to eq("Post") + end + + + + + + + + +end \ No newline at end of file diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb new file mode 100644 index 000000000..d438634fd --- /dev/null +++ b/spec/models/post_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +describe Post do + + let(:user){create(:user)} + let(:post){user.posts_written.create(attributes_for(:post))} + + it "is valid with valid parameters" do + expect(post).to be_valid + end + + it {should belong_to(:author)} + + it {should belong_to(:receiver)} + + it {should have_many(:comments)} + + it {should have_many(:likes)} + + + + + + + +end \ No newline at end of file diff --git a/spec/models/profile_spec.rb b/spec/models/profile_spec.rb new file mode 100644 index 000000000..3df4f4c98 --- /dev/null +++ b/spec/models/profile_spec.rb @@ -0,0 +1,35 @@ +require 'rails_helper' + +describe Profile do + + let(:profile){build(:profile)} + + it "should be valid with valid parameters" do + expect(profile).to be_valid + end + + it { should validate_length_of(:first_name).is_at_most(40).on(:update)} + + it { should validate_length_of(:last_name).is_at_most(40).on(:update)} + + it { should validate_length_of(:college).is_at_most(40).on(:update)} + + it { should validate_length_of(:hometown).is_at_most(40).on(:update)} + + it { should validate_length_of(:currently_lives).is_at_most(40).on(:update)} + + it { should validate_length_of(:words_to_live_by).is_at_most(300).on(:update)} + + it { should validate_length_of(:about_me).is_at_most(300).on(:update)} + + + it { should validate_length_of(:telephone).is_at_most(15).on(:update)} + + it { should validate_length_of(:telephone).is_at_least(10).on(:update)} + + it {should belong_to(:user)} + + + + +end \ No newline at end of file diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 000000000..5eb5588d4 --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' + +describe User do + + let(:user){create(:user)} + + it "is valid with an email and a password" do + expect(user).to be_valid + end + it { should validate_uniqueness_of(:email) } + + it "should have an email in the correct format" do + expect(user.email.split('').include?("@")).to be true + end + + it { should validate_length_of(:password).is_at_least(6).on(:create)} + + it { should have_secure_password } + + it { should have_one(:profile)} + + it { should accept_nested_attributes_for(:profile)} + + it { should have_many(:posts_written)} + + it { should have_many(:posts_received)} + + it { should have_many(:comments_written)} + + it { should have_many(:likes_given)} + + let(:post){user.posts_written.create(attributes_for(:post))} + it "likes_post should return 1 if the user likes the post" do + user.likes_given.create(attributes_for(:like, likeable_id: post.id, likeable_type: "Post")) + expect(user.likes_post?(post.id, "Post").length).to eq(1) + end + + it "likes_post should return 0 if the user does not like the post" do + expect(user.likes_post?(post.id, "Post").length).to eq(0) + end + + + + + + + + +end \ No newline at end of file diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 000000000..6d1004b76 --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,76 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +ENV['RAILS_ENV'] ||= 'test' +require File.expand_path('../../config/environment', __FILE__) +# Prevent database truncation if the environment is production +abort("The Rails environment is running in production mode!") if Rails.env.production? +require 'spec_helper' +require 'rspec/rails' +require 'factory_girl_rails' +require 'capybara/rails' + +# Add additional requires below this line. Rails is not loaded until this point! + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } + +# Checks for pending migration and applies them before tests are run. +# If you are not using ActiveRecord, you can remove this line. +ActiveRecord::Migration.maintain_test_schema! +Rails.logger.level = 4 + +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, :type => :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://relishapp.com/rspec/rspec-rails/docs + config.infer_spec_type_from_file_location! + + # Filter lines from Rails gems in backtraces. + config.filter_rails_from_backtrace! + config.include FactoryGirl::Syntax::Methods + config.include UserMacros + config.include ControllerHelper + config.include Capybara::DSL + + + + +end +Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end +end + # arbitrary gems may also be filtered via: + # config.filter_gems_from_backtrace("gem name") + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 000000000..b3260c06c --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,100 @@ +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + config.disable_monkey_patching! + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/spec/support/controller_helper.rb b/spec/support/controller_helper.rb new file mode 100644 index 000000000..d37e60858 --- /dev/null +++ b/spec/support/controller_helper.rb @@ -0,0 +1,17 @@ +module ControllerHelper + def login(user) + cookies[:auth_token] = user.auth_token + end + + def logout + cookies.delete(:auth_token) + end + + def current_user + User.find(cookies[:auth_token]) if User.exists?(cookies[:auth_token]) && cookies[:auth_token] + end + + def signed_in_user? + !!current_user + end +end \ No newline at end of file diff --git a/spec/support/user_macros.rb b/spec/support/user_macros.rb new file mode 100644 index 000000000..451e21001 --- /dev/null +++ b/spec/support/user_macros.rb @@ -0,0 +1,22 @@ +module UserMacros + + def sign_up(email) + fill_in "user[email]", with: email + fill_in "user[password]", with: "foobarfoobar" + fill_in "user[password_confirmation]", with: "foobarfoobar" + end + + def sign_in(user) + fill_in 'email', with: user.email + fill_in 'password', with: user.password + click_button 'Log In' + end + + def sign_out + click_link "Logout" + end + + + + +end \ No newline at end of file diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/controllers/comments_controller_test.rb b/test/controllers/comments_controller_test.rb new file mode 100644 index 000000000..a812ddae9 --- /dev/null +++ b/test/controllers/comments_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class CommentsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/friends_controller_test.rb b/test/controllers/friends_controller_test.rb new file mode 100644 index 000000000..35ac04973 --- /dev/null +++ b/test/controllers/friends_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FriendsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/likes_controller_test.rb b/test/controllers/likes_controller_test.rb new file mode 100644 index 000000000..78e007545 --- /dev/null +++ b/test/controllers/likes_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class LikesControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/photos_controller_test.rb b/test/controllers/photos_controller_test.rb new file mode 100644 index 000000000..6f4fb0858 --- /dev/null +++ b/test/controllers/photos_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PhotosControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/posts_controller_test.rb b/test/controllers/posts_controller_test.rb new file mode 100644 index 000000000..12c4a7fd0 --- /dev/null +++ b/test/controllers/posts_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PostsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb new file mode 100644 index 000000000..6135ce6af --- /dev/null +++ b/test/controllers/sessions_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class SessionsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/static_pages_controller_test.rb b/test/controllers/static_pages_controller_test.rb new file mode 100644 index 000000000..76b4b38eb --- /dev/null +++ b/test/controllers/static_pages_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class StaticPagesControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/timelines_controller_test.rb b/test/controllers/timelines_controller_test.rb new file mode 100644 index 000000000..63c8065c6 --- /dev/null +++ b/test/controllers/timelines_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class TimelinesControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb new file mode 100644 index 000000000..6c3da770c --- /dev/null +++ b/test/controllers/users_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UsersControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/.keep b/test/fixtures/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/comments.yml b/test/fixtures/comments.yml new file mode 100644 index 000000000..80aed36e3 --- /dev/null +++ b/test/fixtures/comments.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/likes.yml b/test/fixtures/likes.yml new file mode 100644 index 000000000..80aed36e3 --- /dev/null +++ b/test/fixtures/likes.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/photos.yml b/test/fixtures/photos.yml new file mode 100644 index 000000000..80aed36e3 --- /dev/null +++ b/test/fixtures/photos.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/post_texts.yml b/test/fixtures/post_texts.yml new file mode 100644 index 000000000..80aed36e3 --- /dev/null +++ b/test/fixtures/post_texts.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/posts.yml b/test/fixtures/posts.yml new file mode 100644 index 000000000..80aed36e3 --- /dev/null +++ b/test/fixtures/posts.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/profiles.yml b/test/fixtures/profiles.yml new file mode 100644 index 000000000..3830afc88 --- /dev/null +++ b/test/fixtures/profiles.yml @@ -0,0 +1,13 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + first_name: MyString + last_name: MyString + birthday: 2016-08-10 + gender: MyString + +two: + first_name: MyString + last_name: MyString + birthday: 2016-08-10 + gender: MyString diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 000000000..80aed36e3 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/videos.yml b/test/fixtures/videos.yml new file mode 100644 index 000000000..80aed36e3 --- /dev/null +++ b/test/fixtures/videos.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/helpers/.keep b/test/helpers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/models/comment_test.rb b/test/models/comment_test.rb new file mode 100644 index 000000000..b6d6131a9 --- /dev/null +++ b/test/models/comment_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class CommentTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/like_test.rb b/test/models/like_test.rb new file mode 100644 index 000000000..1eea9915b --- /dev/null +++ b/test/models/like_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class LikeTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/photo_test.rb b/test/models/photo_test.rb new file mode 100644 index 000000000..e2ec03a1b --- /dev/null +++ b/test/models/photo_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PhotoTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/post_test.rb b/test/models/post_test.rb new file mode 100644 index 000000000..6d9d463a7 --- /dev/null +++ b/test/models/post_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PostTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/post_text_test.rb b/test/models/post_text_test.rb new file mode 100644 index 000000000..466c0d7d3 --- /dev/null +++ b/test/models/post_text_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PostTextTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/profile_test.rb b/test/models/profile_test.rb new file mode 100644 index 000000000..3dfa94302 --- /dev/null +++ b/test/models/profile_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ProfileTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 000000000..82f61e010 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/video_test.rb b/test/models/video_test.rb new file mode 100644 index 000000000..cf3f0b175 --- /dev/null +++ b/test/models/video_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class VideoTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 000000000..92e39b2d7 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,10 @@ +ENV['RAILS_ENV'] ||= 'test' +require File.expand_path('../../config/environment', __FILE__) +require 'rails/test_help' + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... +end diff --git a/tmp/.keep b/tmp/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/assets/javascripts/.keep b/vendor/assets/javascripts/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep new file mode 100644 index 000000000..e69de29bb