├── .gitignore ├── .idea ├── .generators ├── .rakeTasks ├── dataSources.local.xml ├── dataSources.xml ├── dataSources │ ├── 133cfd96-24dc-4e1a-8481-5e6a0cc2d454.xml │ └── 133cfd96-24dc-4e1a-8481-5e6a0cc2d454 │ │ └── storage_v2 │ │ └── _src_ │ │ └── schema │ │ └── main.uQUzAA.meta ├── misc.xml ├── modules.xml ├── my_dev_portal_dashboard.iml ├── vcs.xml └── workspace.xml ├── .rspec ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── Rakefile ├── app ├── assets │ ├── config │ │ └── manifest.js │ ├── images │ │ ├── add.svg │ │ ├── add_large.svg │ │ ├── back.svg │ │ ├── blog.svg │ │ ├── delete.svg │ │ ├── down-arrow.svg │ │ ├── drop-arrow.svg │ │ ├── edit.svg │ │ ├── facebook.svg │ │ ├── github-large.svg │ │ ├── github.svg │ │ ├── left_arrow.svg │ │ ├── linkedin.svg │ │ ├── mydevportal-small.svg │ │ ├── mydevportal.svg │ │ ├── portfolio.svg │ │ ├── right_arrow.svg │ │ ├── settings.svg │ │ ├── slider │ │ │ └── arrow__right--blue.svg │ │ ├── track.svg │ │ ├── twitter.svg │ │ ├── view.svg │ │ └── website.svg │ ├── javascripts │ │ ├── abouts.coffee │ │ ├── application.js │ │ ├── cable.js │ │ ├── channels │ │ │ └── .keep │ │ ├── dashboard.js │ │ ├── dashboard │ │ │ ├── dashboard.coffee │ │ │ ├── job_applications.js │ │ │ └── portfolio_select.js │ │ ├── homepage.js │ │ ├── portfolio.js │ │ └── portfolio │ │ │ └── portfolio.js │ └── stylesheets │ │ ├── application-dashboard.css.scss │ │ ├── application-themes.css.scss │ │ ├── application.css.scss │ │ ├── component-slider.css │ │ ├── dashboard │ │ ├── abouts.scss │ │ ├── blogs.css.scss │ │ ├── dashboard.scss │ │ ├── home.scss │ │ ├── job_applications.scss │ │ ├── portfolio_config.scss │ │ ├── portfolio_preview.scss │ │ ├── projects.scss │ │ └── technologies.scss │ │ ├── devise.scss │ │ ├── homepage.scss │ │ ├── scaffolds.scss │ │ ├── slider_component │ │ ├── config │ │ │ ├── _colors.scss │ │ │ ├── _labs-bar.scss │ │ │ ├── _mixins.scss │ │ │ ├── _reset.scss │ │ │ ├── _typography.scss │ │ │ └── _variables.scss │ │ ├── slider.scss │ │ └── slider │ │ │ ├── _funtionality.scss │ │ │ └── _styling.scss │ │ └── themes │ │ ├── default.scss │ │ └── portfolio_gallary.scss ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── controllers │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ ├── dashboard │ │ ├── abouts_controller.rb │ │ ├── blogs_controller.rb │ │ ├── dashboard_controller.rb │ │ ├── job_applications_controller.rb │ │ ├── portfolio_headers_controller.rb │ │ ├── portfolios_controller.rb │ │ ├── projects_controller.rb │ │ ├── technologies_controller.rb │ │ └── users_controller.rb │ ├── front_end │ │ └── portfolio_controller.rb │ ├── home_controller.rb │ └── users │ │ ├── confirmations_controller.rb │ │ ├── omniauth_callbacks_controller.rb │ │ ├── passwords_controller.rb │ │ ├── registrations_controller.rb │ │ ├── sessions_controller.rb │ │ └── unlocks_controller.rb ├── helpers │ ├── application_helper.rb │ └── dashboard_helper.rb ├── jobs │ └── application_job.rb ├── mailers │ └── application_mailer.rb ├── models │ ├── about.rb │ ├── application_record.rb │ ├── concerns │ │ └── .keep │ ├── job_application.rb │ ├── portfolio.rb │ ├── portfolio_header.rb │ ├── project.rb │ ├── technology.rb │ └── user.rb ├── uploaders │ ├── avatar_image_uploader.rb │ ├── cover_image_uploader.rb │ └── image_uploader.rb ├── validators │ ├── css_hex_color_validator.rb │ ├── max_projects_validator.rb │ └── url_validator.rb └── views │ ├── dashboard │ ├── abouts │ │ ├── _form.html.haml │ │ ├── edit.html.haml │ │ └── new.html.haml │ ├── blogs │ │ └── show.html.haml │ ├── dashboard │ │ ├── _select_active_portfolio.html.haml │ │ └── index.html.haml │ ├── job_applications │ │ ├── _applications_list.html.haml │ │ ├── _form.html.haml │ │ ├── edit.html.haml │ │ ├── index.csv.erb │ │ ├── index.html.haml │ │ ├── index.js.erb │ │ ├── new.html.haml │ │ └── show.html.haml │ ├── portfolio_headers │ │ ├── _form.html.haml │ │ ├── _show.html.haml │ │ ├── edit.html.haml │ │ └── new.html.haml │ ├── portfolios │ │ ├── _change_colors.html.haml │ │ ├── _change_display_image.html.haml │ │ ├── _change_font_colors.html.haml │ │ ├── _change_header_font_colors.html.haml │ │ ├── _change_header_images.html.haml │ │ ├── _change_header_text.html.haml │ │ ├── _change_technologies.html.haml │ │ ├── _change_theme.html.haml │ │ ├── _change_url.html.haml │ │ ├── _current_avatar_image.html.haml │ │ ├── _current_cover_image.html.haml │ │ ├── _new.html.haml │ │ ├── edit.html.haml │ │ └── preview.html.haml │ ├── projects │ │ ├── _form.html.haml │ │ ├── _project_sidebar.html.haml │ │ ├── _show.html.haml │ │ ├── edit.html.haml │ │ └── new.html.haml │ └── technologies │ │ ├── _form.html.haml │ │ ├── _show.html.haml │ │ ├── edit.html.haml │ │ └── new.html.haml │ ├── front_end │ └── portfolio │ │ ├── components │ │ ├── _default_footer.html.haml │ │ ├── _default_header.html.haml │ │ ├── _default_technologies.html.haml │ │ ├── _portfolio_gallary.html.haml │ │ └── _portfolio_slider.html.haml │ │ ├── show.html.haml │ │ └── themes │ │ ├── _default.html.haml │ │ └── _default_gallary.html.haml │ ├── home │ └── index.html.haml │ ├── layouts │ ├── application.html.haml │ ├── dashboard.html.haml │ ├── front_end │ │ └── portfolio.html.haml │ ├── mailer.html.erb │ └── mailer.text.erb │ └── users │ ├── confirmations │ └── new.html.erb │ ├── mailer │ ├── confirmation_instructions.html.erb │ ├── email_changed.html.erb │ ├── password_change.html.erb │ ├── reset_password_instructions.html.erb │ └── unlock_instructions.html.erb │ ├── passwords │ ├── edit.html.erb │ └── new.html.erb │ ├── registrations │ ├── edit.html.erb │ └── new.html.erb │ ├── sessions │ └── new.html.erb │ ├── shared │ └── _links.html.erb │ └── unlocks │ └── new.html.erb ├── bin ├── bundle ├── rails ├── rake ├── setup ├── spring ├── update └── yarn ├── code_of_conduct.md ├── config.ru ├── config ├── application.example.yml ├── application.rb ├── boot.rb ├── cable.yml ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── application_controller_renderer.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── carrier_wave.rb │ ├── cookies_serializer.rb │ ├── devise.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── themes.rb │ └── wrap_parameters.rb ├── locales │ ├── devise.en.yml │ └── en.yml ├── puma.rb ├── routes.rb ├── secrets.yml └── spring.rb ├── db ├── migrate │ ├── 20171204231450_devise_create_users.rb │ ├── 20171205193732_create_portfolios.rb │ ├── 20171207235120_create_projects.rb │ ├── 20171210212628_create_technologies.rb │ ├── 20171211213207_create_portfolio_headers.rb │ ├── 20171212225416_create_abouts.rb │ ├── 20171219205323_change_column_name.rb │ ├── 20171226173830_create_job_applications.rb │ └── 20171231161435_add_options_to_users.rb ├── schema.rb └── seeds.rb ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── log └── .keep ├── package.json ├── public ├── 404.html ├── 422.html ├── 500.html ├── apple-touch-icon-precomposed.png ├── apple-touch-icon.png ├── favicon.ico ├── robots.txt └── uploads │ ├── project │ └── image │ │ └── 1 │ │ ├── large_test.jpg │ │ ├── medium_test.jpg │ │ ├── small_test.jpg │ │ ├── test.jpg │ │ └── thumb_test.jpg │ └── tmp │ ├── 1512691563-15357-0002-7928 │ ├── IMG_0736.JPG │ └── thumb_IMG_0736.JPG │ ├── 1512691666-15357-0003-7880 │ ├── IMG_0736.JPG │ └── thumb_IMG_0736.JPG │ ├── 1512692438-16702-0001-5998 │ ├── IMG_0736.JPG │ └── thumb_IMG_0736.JPG │ └── 1512692498-16702-0002-9124 │ ├── IMG_0736.JPG │ └── thumb_IMG_0736.JPG ├── spec ├── controllers │ ├── dashboard │ │ ├── abouts_controller_spec.rb │ │ ├── dashboard_controller_spec.rb │ │ ├── job_applications_controller_spec.rb │ │ ├── portfolio_headers_controller_spec.rb │ │ ├── portfolios_controller_spec.rb │ │ ├── projects_controller_spec.rb │ │ └── technologies_controller_spec.rb │ └── home_controller_spec.rb ├── factories.rb ├── fixtures │ └── images │ │ └── test.jpg ├── models │ ├── about_spec.rb │ ├── job_application_spec.rb │ ├── portfolio_header_spec.rb │ ├── portfolio_spec.rb │ ├── project_spec.rb │ └── technology_spec.rb ├── rails_helper.rb ├── routing │ └── job_applications_routing_spec.rb ├── spec_helper.rb └── support │ ├── controller_macros.rb │ └── custom_validations.rb ├── tmp └── .keep └── vendor └── .keep /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | /tmp/* 17 | !/log/.keep 18 | !/tmp/.keep 19 | 20 | /node_modules 21 | /yarn-error.log 22 | 23 | .byebug_history 24 | 25 | # Ignore application configuration 26 | /config/application.yml 27 | 28 | # Ignore images uploaded by carrierwave 29 | /public/uploads 30 | -------------------------------------------------------------------------------- /.idea/.generators: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /.idea/dataSources.local.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | false 8 | *:main 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sqlite.xerial 6 | true 7 | true 8 | $PROJECT_DIR$/config/database.yml 9 | org.sqlite.JDBC 10 | jdbc:sqlite:$PROJECT_DIR$/db/development.sqlite3 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/dataSources/133cfd96-24dc-4e1a-8481-5e6a0cc2d454/storage_v2/_src_/schema/main.uQUzAA.meta: -------------------------------------------------------------------------------- 1 | #n:main 2 | ! [0, 0, null, null, -2147483648, -2147483648] 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | git_source(:github) do |repo_name| 4 | repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") 5 | "https://github.com/#{repo_name}.git" 6 | end 7 | 8 | 9 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 10 | gem 'rails', '~> 5.1.4' 11 | # Use devise for authentication 12 | gem 'devise' 13 | # Use mailgun for mailer 14 | gem 'mailgun_rails' 15 | # Use figaro to manage environment variables 16 | gem 'figaro' 17 | # Use Postgres as database 18 | gem 'pg' 19 | # Gravitar API 20 | gem 'gravtastic' 21 | # Use Haml instead of ERb 22 | gem 'haml-rails' 23 | # Linter for haml 24 | gem 'haml-lint' 25 | # Use carrierwave and mini magik for managing image uploads 26 | gem 'carrierwave' 27 | gem 'mini_magick' 28 | # Use fog-aws for carrierwave cloud storage 29 | gem 'fog-aws' 30 | # Filterrifc for filtering ActiveRecord 31 | gem 'filterrific' 32 | # Bootstrap 4 for rails 33 | gem 'bootstrap', '~> 4.0.0.beta2.1' 34 | # jquery color picker 35 | gem 'jquery-minicolors-rails' 36 | # jQuery for Rails 37 | gem 'jquery-rails' 38 | # jQuery turbolinks 39 | gem 'jquery-turbolinks' 40 | # Use Puma as the app server 41 | gem 'puma', '~> 3.7' 42 | # Use SCSS for stylesheets 43 | gem 'sass-rails', '~> 5.0' 44 | # Use Uglifier as compressor for JavaScript assets 45 | gem 'uglifier', '>= 1.3.0' 46 | # See https://github.com/rails/execjs#readme for more supported runtimes 47 | # gem 'therubyracer', platforms: :ruby 48 | 49 | # Use CoffeeScript for .coffee assets and views 50 | gem 'coffee-rails', '~> 4.2' 51 | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks 52 | gem 'turbolinks', '~> 5' 53 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 54 | gem 'jbuilder', '~> 2.5' 55 | # Use Redis adapter to run Action Cable in production 56 | # gem 'redis', '~> 3.0' 57 | # Use ActiveModel has_secure_password 58 | # gem 'bcrypt', '~> 3.1.7' 59 | 60 | # Use Capistrano for deployment 61 | # gem 'capistrano-rails', group: :development 62 | 63 | group :development, :test do 64 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 65 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 66 | # Adds support for Capybara system testing and selenium driver 67 | gem 'capybara', '~> 2.13' 68 | gem 'rspec-rails', '~> 3.6' 69 | gem 'rails-controller-testing' 70 | gem 'selenium-webdriver' 71 | gem 'sqlite3' 72 | gem 'shoulda-matchers', '~> 3.1' 73 | gem 'factory_girl_rails' 74 | gem 'faker' 75 | end 76 | 77 | group :development do 78 | # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. 79 | gem 'web-console', '>= 3.3.0' 80 | gem 'listen', '>= 3.0.5', '< 3.2' 81 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 82 | gem 'spring' 83 | gem 'spring-watcher-listen', '~> 2.0.0' 84 | end 85 | 86 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 87 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 88 | ruby "2.3.5" 89 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 SWLivingstone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /app/assets/images/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/add_large.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/assets/images/blog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/down-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/assets/images/drop-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/assets/images/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/assets/images/facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/assets/images/github-large.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/assets/images/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/left_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/linkedin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/portfolio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/right_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/assets/images/slider/arrow__right--blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | arrow__right--blue 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/assets/images/track.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/view.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/assets/images/website.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/abouts.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's 5 | // vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. JavaScript code in this file should be added after the last require_* statement. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require rails-ujs 14 | //= require jquery 15 | //= require jquery.turbolinks 16 | //= require popper 17 | //= require bootstrap-sprockets 18 | //= require turbolinks 19 | //= require ./homepage.js 20 | //= require ./cable.js 21 | -------------------------------------------------------------------------------- /app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/app/assets/javascripts/channels/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/dashboard.js: -------------------------------------------------------------------------------- 1 | //= require filterrific/filterrific-jquery 2 | //= require jquery.minicolors 3 | //= require_tree ./dashboard 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/dashboard/dashboard.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | $ -> $('.color-picker').minicolors() 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/dashboard/job_applications.js: -------------------------------------------------------------------------------- 1 | ready = function() { 2 | $("#filter-collapse-button").click(function () { 3 | $(".filter-search-box").addClass("hidden"); 4 | $(".show-main").css("grid-template-columns", "auto"); 5 | $("#filter-expand-button").removeClass("hidden") 6 | }); 7 | 8 | $("#filter-expand-button").click(function () { 9 | $("#filter-expand-button").addClass("hidden"); 10 | $(".show-main").css("grid-template-columns", "265px auto minmax(0px, 265px)"); 11 | $(".filter-search-box").removeClass("hidden") 12 | }); 13 | } 14 | 15 | $(document).ready(ready) 16 | $(document).on('turbolinks:load', ready) 17 | -------------------------------------------------------------------------------- /app/assets/javascripts/dashboard/portfolio_select.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | // always pass csrf tokens on ajax calls 3 | $.ajaxSetup({ 4 | headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } 5 | }); 6 | }); 7 | 8 | $(document).on('change', '#user_options', function(event) { 9 | var user_options = $(this).val(); 10 | $.ajax({ 11 | type: "PATCH", 12 | url: "/select_active_portfolio", 13 | data: { id: user_options } 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /app/assets/javascripts/homepage.js: -------------------------------------------------------------------------------- 1 | /* 2 | On click hides/unhides the div that matches the element id. 3 | */ 4 | 5 | $(document).ready(function(){ 6 | $(".feature").click(function () { 7 | var id = this.id 8 | var element = id.concat('-detail') 9 | if ($('#' + element).hasClass("hidden")) { 10 | $(".detail").addClass("hidden"); 11 | $(".feature").removeClass("active-feature"); 12 | $('#' + element).removeClass("hidden"); 13 | $(this).addClass("active-feature"); 14 | 15 | $('html, body').animate({ 16 | scrollTop: $('#' + element).offset().top 17 | }, 300); 18 | } 19 | else { 20 | $('#' + element).addClass("hidden"); 21 | $(".feature").removeClass("active-feature"); 22 | } 23 | }); 24 | }) 25 | -------------------------------------------------------------------------------- /app/assets/javascripts/portfolio.js: -------------------------------------------------------------------------------- 1 | //= require_tree ./portfolio 2 | -------------------------------------------------------------------------------- /app/assets/javascripts/portfolio/portfolio.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Replace all SVG images with inline SVG 3 | */ 4 | ready = function() { 5 | $('img[src$=".svg"]').each(function() { 6 | var $img = jQuery(this); 7 | var imgURL = $img.attr('src'); 8 | var attributes = $img.prop("attributes"); 9 | 10 | $.get(imgURL, function(data) { 11 | // Get the SVG tag, ignore the rest 12 | var $svg = jQuery(data).find('svg'); 13 | 14 | // Remove any invalid XML tags 15 | $svg = $svg.removeAttr('xmlns:a'); 16 | 17 | // Loop through IMG attributes and apply on SVG 18 | $.each(attributes, function() { 19 | $svg.attr(this.name, this.value); 20 | }); 21 | 22 | // Replace IMG with SVG 23 | $img.replaceWith($svg); 24 | }, 'xml'); 25 | }); 26 | } 27 | $(document).ready(ready) 28 | $(document).on('turbolinks:load', ready) 29 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application-dashboard.css.scss: -------------------------------------------------------------------------------- 1 | /* 2 | *= require_self 3 | *= require_tree ./dashboard 4 | */ 5 | 6 | @import 'bootstrap'; 7 | @import 'jquery.minicolors'; 8 | 9 | body { 10 | font-family: 'Roboto', sans-serif; 11 | } 12 | 13 | a:hover { 14 | text-decoration: none; 15 | color: inherit; 16 | } 17 | 18 | html { 19 | min-height: 100%; 20 | width: 100%; 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | .alert { 26 | margin-bottom: 0px; 27 | } 28 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application-themes.css.scss: -------------------------------------------------------------------------------- 1 | /* 2 | *= require_self 3 | *= require_tree ./themes 4 | */ 5 | 6 | @import 'bootstrap'; 7 | 8 | body { 9 | font-family: 'Roboto', sans-serif; 10 | } 11 | 12 | a:hover { 13 | text-decoration: none; 14 | color: inherit; 15 | } 16 | 17 | html { 18 | height: 100%; 19 | width: 100%; 20 | margin: 0; 21 | padding: 0; 22 | } 23 | 24 | .alert { 25 | margin-bottom: 0px; 26 | } 27 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css.scss: -------------------------------------------------------------------------------- 1 | @import 'bootstrap'; 2 | 3 | @import 'homepage'; 4 | @import 'devise'; 5 | 6 | body { 7 | font-family: 'Roboto', sans-serif; 8 | } 9 | 10 | a:hover { 11 | text-decoration: none; 12 | color: inherit; 13 | } 14 | 15 | html { 16 | height: 100%; 17 | width: 100%; 18 | margin: 0; 19 | padding: 0; 20 | } 21 | 22 | .alert { 23 | margin-bottom: 0px; 24 | } 25 | -------------------------------------------------------------------------------- /app/assets/stylesheets/component-slider.css: -------------------------------------------------------------------------------- 1 | /* 2 | *= require_self 3 | *= require ./slider_component/slider 4 | */ 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/dashboard/abouts.scss: -------------------------------------------------------------------------------- 1 | .about-main { 2 | display: grid; 3 | grid-template-columns: auto 615px auto; 4 | grid-template-rows: auto; 5 | margin-top: 20px; 6 | grid-gap: 20px; 7 | } 8 | 9 | .about-form h4 { 10 | justify-self: center; 11 | text-align: center; 12 | padding-bottom: 10px; 13 | margin-bottom: 20px; 14 | border-bottom: 2px solid white; 15 | width: 400px; 16 | } 17 | 18 | .about-form { 19 | color: white; 20 | background-color: #1c1c1c; 21 | box-shadow: 3px 3px 1px 0px black; 22 | border-radius: 5px; 23 | padding: 30px 35px 20px 35px; 24 | grid-column: 2 / 3; 25 | display: grid; 26 | } 27 | 28 | .form-about .actions { 29 | justify-self: end; 30 | } 31 | 32 | .about-form-container { 33 | background-color: #606060; 34 | box-shadow: 3px 3px 1px 0px black; 35 | padding: 15px; 36 | border-radius: 5px; 37 | } 38 | 39 | .form-about { 40 | display: grid; 41 | grid-template-columns: 510px; 42 | grid-template-rows: repeat(7, 70px) 100px 350px; 43 | } 44 | 45 | .form-about .field input { 46 | width: 510px; 47 | } 48 | 49 | .about-me-input { 50 | height: 300px; 51 | width: 510px; 52 | } 53 | 54 | .about-me-brief-input { 55 | height: 50px; 56 | width: 510px; 57 | } 58 | 59 | @media only screen and (min-width: 1200px) { 60 | .form-about { 61 | grid-template-columns: 510px 510px; 62 | grid-template-rows: repeat(7, 70px); 63 | grid-column-gap: 40px; 64 | } 65 | 66 | .form-about .actions { 67 | grid-column: span 2; 68 | } 69 | 70 | .about-main { 71 | grid-template-columns: auto 1160px auto; 72 | } 73 | 74 | .field.about-me { 75 | grid-column: span 2; 76 | grid-row: span 3; 77 | } 78 | 79 | .about-me-input { 80 | height: 150px; 81 | width: 1060px; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/assets/stylesheets/dashboard/blogs.css.scss: -------------------------------------------------------------------------------- 1 | .place-holder { 2 | color: white; 3 | margin-top: 75px; 4 | } 5 | 6 | .place-holder a { 7 | font-weight: bold; 8 | text-decoration: underline; 9 | } 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/dashboard/home.scss: -------------------------------------------------------------------------------- 1 | .home-container { 2 | display: grid; 3 | } 4 | 5 | .welcome-box { 6 | justify-self: center; 7 | margin-top: 10vh; 8 | display: grid; 9 | justify-items: center; 10 | grid-gap: 20px; 11 | } 12 | 13 | .go-to-portfolio { 14 | background-color: #24a3b7; 15 | font-size: 28px; 16 | box-shadow: 3px 3px 1px black; 17 | padding: 10px; 18 | } 19 | 20 | .go-to-portfolio a { 21 | color: white; 22 | height: 68px; 23 | padding: 12px; 24 | } 25 | 26 | .new-user-box-container { 27 | background-color: #1c1c1c; 28 | padding: 30px 35px 20px 35px; 29 | border-radius: 5px; 30 | color: white; 31 | box-shadow: 3px 3px 2px black; 32 | } 33 | 34 | .new-user-box { 35 | display: grid; 36 | grid-template-columns: 350px; 37 | background-color: #606060; 38 | padding: 20px; 39 | border-radius: 5px; 40 | grid-gap: 10px; 41 | box-shadow: 3px 3px 2px black; 42 | } 43 | 44 | .new-user-box a { 45 | color: white; 46 | font-weight: bold; 47 | } 48 | 49 | .new-user-box h2 { 50 | text-align: center; 51 | } 52 | -------------------------------------------------------------------------------- /app/assets/stylesheets/dashboard/portfolio_preview.scss: -------------------------------------------------------------------------------- 1 | .preview-container { 2 | padding: 30px 65px 20px 65px; 3 | } 4 | 5 | .preview { 6 | box-shadow: 3px 3px 1px 0px black; 7 | } 8 | -------------------------------------------------------------------------------- /app/assets/stylesheets/dashboard/technologies.scss: -------------------------------------------------------------------------------- 1 | // Add technology form 2 | 3 | .technologies-main { 4 | display: grid; 5 | grid-template-columns: auto 550px auto; 6 | margin-top: 20px; 7 | grid-gap: 20px; 8 | } 9 | 10 | .technologies-form-container { 11 | color: white; 12 | background-color: #1c1c1c; 13 | box-shadow: 3px 3px 1px 0px black; 14 | border-radius: 5px; 15 | padding: 30px 35px 20px 35px; 16 | grid-column: 2 / 3; 17 | justify-self: center; 18 | display: grid; 19 | } 20 | 21 | .technologies-form-container h4 { 22 | justify-self: center; 23 | text-align: center; 24 | padding-bottom: 10px; 25 | margin-bottom: 20px; 26 | border-bottom: 2px solid white; 27 | width: 400px; 28 | } 29 | 30 | .technologies-form-container p { 31 | margin-bottom: 5px; 32 | } 33 | 34 | .technolgies-form-sub-container { 35 | background-color: #606060; 36 | box-shadow: 3px 3px 1px 0px black; 37 | padding: 15px; 38 | border-radius: 5px; 39 | } 40 | 41 | .technologies-explained { 42 | margin-bottom: 30px; 43 | } 44 | 45 | .form-technology { 46 | display: grid; 47 | grid-template-columns: 230px 230px; 48 | grid-template-rows: 40px 40px 50px; 49 | } 50 | 51 | .form-technology div:nth-child(1) { 52 | grid-row: 1 / span 2; 53 | } 54 | 55 | .show-select { 56 | display: grid; 57 | grid-template-columns: 150px 50px; 58 | grid-template-rows: 25px; 59 | } 60 | 61 | .exp-input { 62 | display: grid; 63 | grid-template-columns: 150px 50px; 64 | grid-template-rows: 30px; 65 | justify-self: end; 66 | } 67 | 68 | .form-technology .actions { 69 | justify-self: end; 70 | align-self: end; 71 | grid-column: 2 / 3; 72 | } 73 | 74 | .form-technology .cancel { 75 | margin-right: 10px; 76 | } 77 | 78 | // show technology index 79 | 80 | .technologies-show-main-container { 81 | grid-column: span 3; 82 | justify-self: center; 83 | padding: 30px 35px 20px 35px; 84 | background-color: #1c1c1c; 85 | box-shadow: 3px 3px 1px 0px black; 86 | border-radius: 5px; 87 | width: 800px; 88 | } 89 | 90 | .technologies-show-main-container .table { 91 | background-color: #606060; 92 | box-shadow: 3px 3px 1px 0px black; 93 | border-radius: 5px; 94 | width: 100%; 95 | } 96 | 97 | .edit-delete-technology { 98 | display: grid; 99 | grid-template-columns: 25px 25px; 100 | justify-content: center; 101 | } 102 | 103 | .technology-edit-icon { 104 | background-image: image-url('edit.svg'); 105 | background-position: center; 106 | background-repeat: no-repeat; 107 | height: 24px; 108 | } 109 | 110 | .technology-delete-icon { 111 | background-image: image-url('delete.svg'); 112 | background-position: center; 113 | background-repeat: no-repeat; 114 | height: 24px; 115 | } 116 | 117 | @media only screen and (max-width: 830px) { 118 | .technologies-show-main-container { 119 | width: 500px; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/assets/stylesheets/devise.scss: -------------------------------------------------------------------------------- 1 | .devise { 2 | min-height: 100vh; 3 | background-color: #1c1c1c; 4 | display: grid; 5 | justify-content: center; 6 | padding-top: 10vh; 7 | color: white; 8 | font-size: 18px; 9 | grid-template-columns: 350px; 10 | } 11 | 12 | .devise a { 13 | color: white; 14 | } 15 | 16 | .devise h2 { 17 | background-color: #e12831; 18 | box-shadow: 3px 3px 1px 0px black; 19 | border-radius: 5px 5px 0px 0px; 20 | margin: 0px; 21 | padding: 15px; 22 | font-size: 28px; 23 | } 24 | 25 | .devise form { 26 | margin-top: 10px; 27 | display: grid; 28 | grid-row-gap: 10px; 29 | } 30 | 31 | .devise-form-container { 32 | background-color: #606060; 33 | box-shadow: 3px 3px 1px 0px black; 34 | padding: 15px; 35 | border-radius: 0px 0px 5px 5px; 36 | } 37 | 38 | .devise .actions input { 39 | background-color: #24a3b7; 40 | border: 0px; 41 | border-radius: 5px; 42 | color: white; 43 | padding: 5px 10px 5px 10px; 44 | } 45 | 46 | .devise input { 47 | width: 320px; 48 | } 49 | 50 | .devise .cancel-account { 51 | margin-top: 40px; 52 | } 53 | 54 | .devise .cancel-button { 55 | background-color: #ba2226; 56 | border: 0px; 57 | border-radius: 5px; 58 | color: white; 59 | padding: 5px 10px 5px 10px; 60 | } 61 | 62 | .devise .current-password { 63 | margin-top: 30px; 64 | } 65 | 66 | .devise .remember-me input { 67 | width: 20px; 68 | justify-self: start; 69 | height: 20px; 70 | } 71 | 72 | .devise .remember-me { 73 | display: grid; 74 | grid-template-columns: 150px auto; 75 | align-items: center; 76 | } 77 | -------------------------------------------------------------------------------- /app/assets/stylesheets/scaffolds.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #fff; 3 | color: #333; 4 | margin: 33px; 5 | font-family: verdana, arial, helvetica, sans-serif; 6 | font-size: 13px; 7 | line-height: 18px; 8 | } 9 | 10 | p, ol, ul, td { 11 | font-family: verdana, arial, helvetica, sans-serif; 12 | font-size: 13px; 13 | line-height: 18px; 14 | } 15 | 16 | pre { 17 | background-color: #eee; 18 | padding: 10px; 19 | font-size: 11px; 20 | } 21 | 22 | a { 23 | color: #000; 24 | 25 | &:visited { 26 | color: #666; 27 | } 28 | 29 | &:hover { 30 | color: #fff; 31 | background-color: #000; 32 | } 33 | } 34 | 35 | th { 36 | padding-bottom: 5px; 37 | } 38 | 39 | td { 40 | padding: 0 5px 7px; 41 | } 42 | 43 | div { 44 | &.field, &.actions { 45 | margin-bottom: 10px; 46 | } 47 | } 48 | 49 | #notice { 50 | color: green; 51 | } 52 | 53 | .field_with_errors { 54 | padding: 2px; 55 | background-color: red; 56 | display: table; 57 | } 58 | 59 | #error_explanation { 60 | width: 450px; 61 | border: 2px solid red; 62 | padding: 7px 7px 0; 63 | margin-bottom: 20px; 64 | background-color: #f0f0f0; 65 | 66 | h2 { 67 | text-align: left; 68 | font-weight: bold; 69 | padding: 5px 5px 5px 15px; 70 | font-size: 12px; 71 | margin: -7px -7px 0; 72 | background-color: #c00; 73 | color: #fff; 74 | } 75 | 76 | ul li { 77 | font-size: 12px; 78 | list-style: square; 79 | } 80 | } 81 | 82 | label { 83 | display: block; 84 | } 85 | -------------------------------------------------------------------------------- /app/assets/stylesheets/slider_component/config/_colors.scss: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------- 2 | >>> TABLE OF CONTENTS: 3 | ---------------------------------------------------------------- 4 | 1.0 Neutral 5 | 2.0 Main Colors 6 | 3.0 Color Pallete 7 | 3.0 Grey Scale 8 | --------------------------------------------------------------*/ 9 | 10 | /*-------------------------------------------------------------- 11 | 1.0 Neutral 12 | --------------------------------------------------------------*/ 13 | 14 | $white: #FFF; 15 | $black: #000; 16 | 17 | /*-------------------------------------------------------------- 18 | 2.0 Main color 19 | --------------------------------------------------------------*/ 20 | 21 | $significa: #5050FF; // Blue 22 | 23 | /*-------------------------------------------------------------- 24 | 3.0 Color Pallete 25 | --------------------------------------------------------------*/ 26 | 27 | /*-------------------------------------------------------------- 28 | 4.0 Grey Scale 29 | --------------------------------------------------------------*/ 30 | 31 | $night: #3E4954; // Dark grey 32 | $aluminum: #848995; // Grey 33 | $moon: #E9EFF5; // Lines 34 | $light: #F5F7F9; // Light grey background 35 | -------------------------------------------------------------------------------- /app/assets/stylesheets/slider_component/config/_mixins.scss: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------- 2 | >>> TABLE OF CONTENTS: 3 | ---------------------------------------------------------------- 4 | 1.0 Config 5 | 2.0 Translate 6 | --------------------------------------------------------------*/ 7 | 8 | /*-------------------------------------------------------------- 9 | 1.0 Transition 10 | --------------------------------------------------------------*/ 11 | 12 | @mixin default-transition($param: all) { 13 | transition: $param $normal-transition-time $default-ease; 14 | } 15 | 16 | /*-------------------------------------------------------------- 17 | 2.0 Translate 18 | --------------------------------------------------------------*/ 19 | 20 | @mixin translateX($value: -50%) { 21 | transform: translateX($value); 22 | } 23 | 24 | @mixin translateY($value: -50%) { 25 | transform: translateY($value); 26 | } 27 | 28 | @mixin translateXY($value: -50%) { 29 | transform: translate($value , $value); 30 | } 31 | -------------------------------------------------------------------------------- /app/assets/stylesheets/slider_component/config/_reset.scss: -------------------------------------------------------------------------------- 1 | /*! sanitize.css | CC0 Public Domain | github.com/jonathantneal/sanitize.css */ 2 | pre,textarea{overflow:auto} 3 | [hidden],audio:not([controls]),template{display:none} 4 | details,main,summary{display:block} 5 | input[type=number]{width:auto} 6 | input[type=search],input[type=text],input[type=email]{-webkit-appearance:none} 7 | input[type="*"]{-webkit-appearance:none} 8 | input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none} 9 | progress{display:inline-block} 10 | small{font-size:100%} 11 | textarea{resize:vertical} 12 | [unselectable]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} 13 | *,::after,::before{box-sizing:inherit;border-style:solid;border-width:0} 14 | *{font-size:inherit;line-height:inherit;margin:0;padding:0} 15 | ::after,::before{text-decoration:inherit;vertical-align:inherit} 16 | :root{-ms-overflow-style:-ms-autohiding-scrollbar;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%;box-sizing:border-box;cursor:default;font:16px/1.5 sans-serif;text-rendering:optimizeLegibility} 17 | a{text-decoration:none} 18 | audio,canvas,iframe,img,svg,video{vertical-align:middle} 19 | button,input,select,textarea{background-color:transparent;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.5em} 20 | code,kbd,pre,samp{font-family:monospace,monospace} 21 | nav ol,nav ul{list-style:none} 22 | ul li{list-style: none} 23 | select{-moz-appearance:none;-webkit-appearance:none} 24 | select::-ms-expand{display:none} 25 | select::-ms-value{color:currentColor} 26 | table{border-collapse:collapse;border-spacing:0} 27 | ::-moz-selection{background-color:#B3D4FC;text-shadow:none} 28 | ::selection{background-color:#B3D4FC;text-shadow:none} 29 | @media screen{[hidden~=screen]{display:inherit} 30 | [hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0 0 0 0)!important;position:absolute!important} 31 | } 32 | -------------------------------------------------------------------------------- /app/assets/stylesheets/slider_component/config/_variables.scss: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------- 2 | >>> TABLE OF CONTENTS: 3 | ---------------------------------------------------------------- 4 | 1.0 Font 5 | 2.0 Trasnitions 6 | 3.0 Number of Slides 7 | --------------------------------------------------------------*/ 8 | 9 | /*-------------------------------------------------------------- 10 | 1.0 Font 11 | --------------------------------------------------------------*/ 12 | 13 | $main-font: -apple-system, BlinkMacSystemFont, 14 | "Segoe UI", "Roboto", "Oxygen", 15 | "Ubuntu", "Cantarell", "Fira Sans", 16 | "Droid Sans", "Helvetica Neue", sans-serif; 17 | 18 | /*-------------------------------------------------------------- 19 | 2.0 Transitions 20 | --------------------------------------------------------------*/ 21 | 22 | $normal-transition-time: 0.2s; 23 | $default-ease: ease; 24 | -------------------------------------------------------------------------------- /app/assets/stylesheets/slider_component/slider.scss: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------- 2 | >>> TABLE OF CONTENTS: 3 | ---------------------------------------------------------------- 4 | 1.0 Config 5 | 2.0 Slider 6 | 3.0 All Tutorials 7 | --------------------------------------------------------------*/ 8 | 9 | /*-------------------------------------------------------------- 10 | 1.0 Config 11 | --------------------------------------------------------------*/ 12 | 13 | @import "./config/reset"; 14 | 15 | @import "./config/variables"; 16 | @import "./config/mixins"; 17 | 18 | @import "./config/colors"; 19 | @import "./config/typography"; 20 | 21 | 22 | 23 | /*-------------------------------------------------------------- 24 | 2.0 Slider 25 | --------------------------------------------------------------*/ 26 | 27 | @import "./slider/funtionality"; 28 | @import "./slider/styling"; 29 | 30 | /*-------------------------------------------------------------- 31 | 3.0 All Tutorials 32 | --------------------------------------------------------------*/ 33 | 34 | @import "./config/labs-bar"; 35 | -------------------------------------------------------------------------------- /app/assets/stylesheets/themes/portfolio_gallary.scss: -------------------------------------------------------------------------------- 1 | .portfolio-gallary-container { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, 300px); 4 | grid-auto-rows: 300px; 5 | justify-content: center; 6 | grid-gap: 30px; 7 | margin-left: 5vw; 8 | margin-right: 5vw; 9 | margin-top: 50px; 10 | margin-bottom: 50px; 11 | } 12 | 13 | .portfolio-gallary-container button { 14 | border: 0px; 15 | box-shadow: 1px 1px 1px grey; 16 | } 17 | 18 | .gallary-item { 19 | background-repeat: no-repeat; 20 | background-position: center; 21 | background-size: cover; 22 | } 23 | 24 | .gallary-item:hover { 25 | transform: scale(1.1); 26 | } 27 | 28 | .portfolio-gallary-container .modal-dialog { 29 | max-width: 1100px; 30 | width: 95%; 31 | height: auto; 32 | } 33 | 34 | .portfolio-gallary-container .modal-body { 35 | color: black; 36 | display: grid; 37 | grid-template-rows: auto; 38 | } 39 | 40 | .portfolio-gallary-container .modal-project-image { 41 | max-width:95%; 42 | height: auto; 43 | justify-self: center; 44 | margin-bottom: 20px; 45 | padding-bottom: 20px; 46 | border-bottom: 2px solid grey; 47 | } 48 | -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery with: :exception 3 | 4 | def not_found 5 | raise ActionController::RoutingError.new('Not Found') 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/dashboard/abouts_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::AboutsController < Dashboard::PortfoliosController 2 | before_action :set_record, only: %i[update edit create show] 3 | before_action :set_new_record, only: %i[index new] 4 | before_action :confirm_owner, only: %i[update] 5 | 6 | def index 7 | render @about.portfolio ? 'edit' : 'new' 8 | end 9 | 10 | def show 11 | render 'edit' 12 | end 13 | 14 | def new; end 15 | 16 | def edit; end 17 | 18 | def create 19 | @about.portfolio = @portfolio 20 | 21 | if @about.save 22 | redirect_to portfolio_abouts_path(@portfolio) 23 | flash[:notice] = '"About Me" successfully created!' 24 | else 25 | flash[:alert] = helpers.display_errors(@about) 26 | render 'new' 27 | end 28 | end 29 | 30 | def update 31 | if @about.update(about_params) 32 | redirect_to portfolio_abouts_path(@portfolio) 33 | flash[:notice] = '"About Me" successfully updated' 34 | else 35 | flash[:alert] = helpers.display_errors(@about) 36 | render 'edit' 37 | end 38 | end 39 | 40 | private 41 | 42 | def confirm_owner 43 | return if current_user == @about.portfolio.user 44 | flash[:alert] = 'You are not the owner of that "About Me"' 45 | redirect_to root 46 | end 47 | 48 | def set_new_record 49 | @about = @portfolio.about || About.new 50 | end 51 | 52 | def set_record 53 | @about = params[:id] ? About.find(params[:id]) : About.new(about_params) 54 | end 55 | 56 | def about_params 57 | params.require(:about).permit(:about_me, :location, :about_me_brief, 58 | :github, :email, :linkedin, :facebook, 59 | :twitter, :website) 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /app/controllers/dashboard/blogs_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::BlogsController < Dashboard::DashboardController 2 | def show; end 3 | end 4 | -------------------------------------------------------------------------------- /app/controllers/dashboard/dashboard_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::DashboardController < ApplicationController 2 | layout 'dashboard' 3 | before_action :authenticate_user!, :set_portfolios, :confirm_portfolio_owner 4 | 5 | def index 6 | @dashboard = 'home' 7 | @portfolio_header = @portfolio.portfolio_header || PortfolioHeader.new 8 | @about = @portfolio.about || About.new 9 | @projects = @portfolio.projects.all.order(:order) 10 | @technologies = @portfolio.technologies.all 11 | 12 | if @portfolio_header.header_one && @about.about_me && 13 | @technologies.count.positive? && @projects.count.positive? 14 | @new_user = false 15 | else 16 | @new_user = true 17 | end 18 | end 19 | 20 | private 21 | 22 | def set_portfolios 23 | @portfolio = helpers.active_portfolio 24 | @portfolios = current_user.portfolios.all 25 | end 26 | 27 | def confirm_portfolio_owner 28 | return if current_user == @portfolio.user 29 | flash[:alert] = 'You are not the owner of that or portfolio' 30 | redirect_to root 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/controllers/dashboard/portfolio_headers_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::PortfolioHeadersController < Dashboard::PortfoliosController 2 | before_action :set_record, only: %i[update edit create show] 3 | before_action :set_new_record, only: %i[index new] 4 | before_action :confirm_owner, only: %i[update] 5 | 6 | def index 7 | render @portfolio.portfolio_header ? 'edit' : 'new' 8 | end 9 | 10 | def show 11 | render 'edit' 12 | end 13 | 14 | def new 15 | end 16 | 17 | def edit 18 | end 19 | 20 | def create 21 | @portfolio_header.portfolio = @portfolio 22 | 23 | if @portfolio_header.save 24 | redirect_to edit_user_portfolio_path(current_user, @portfolio) 25 | flash[:notice] = 'Portfolio Header successfully created!' 26 | else 27 | flash[:alert] = helpers.display_errors(@portfolio_header) 28 | render 'dashboard/portfolios/edit' 29 | end 30 | end 31 | 32 | def update 33 | if @portfolio_header.update(portfolio_header_params) 34 | redirect_to edit_user_portfolio_path(current_user, @portfolio) 35 | flash[:notice] = 'Portfolio Header successfully updated' 36 | else 37 | flash[:alert] = helpers.display_errors(@portfolio_header) 38 | render 'dashboard/portfolios/edit' 39 | end 40 | end 41 | 42 | private 43 | 44 | def confirm_owner 45 | unless current_user == @portfolio_header.portfolio.user 46 | flash[:alert] = 'You are not the owner of that portfolio' 47 | redirect_to root 48 | end 49 | end 50 | 51 | def set_new_record 52 | @portfolio_header = @portfolio.portfolio_header || PortfolioHeader.new 53 | end 54 | 55 | def set_record 56 | @portfolio_header = params[:id] ? PortfolioHeader.find(params[:id]) : PortfolioHeader.new(portfolio_header_params) 57 | end 58 | 59 | def portfolio_header_params 60 | params.require(:portfolio_header).permit(:header_one, :header_two, 61 | :cover_image, :avatar_image, 62 | :header_one_color, :header_two_color) 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /app/controllers/dashboard/portfolios_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::PortfoliosController < Dashboard::DashboardController 2 | skip_before_action :confirm_portfolio_owner, only: %i[create] 3 | before_action :set_portfolio, only: %i[new edit update create] 4 | before_action :confirm_owner, only: %i[update] 5 | before_action :set_dashboard 6 | 7 | def new 8 | end 9 | 10 | def edit 11 | end 12 | 13 | def create 14 | new_params = default_params 15 | new_params[:url] = portfolio_params[:url] 16 | @portfolio = current_user.portfolios.new(new_params) 17 | if @portfolio.save 18 | flash[:notice] = 'New Portfolio Created' 19 | redirect_to user_dashboard_index_path(current_user) 20 | else 21 | flash[:alert] = helpers.display_errors(@portfolio) 22 | redirect_to edit_user_portfolio_path(current_user, helpers.active_portfolio) 23 | end 24 | end 25 | 26 | def update 27 | if @portfolio.update(portfolio_params) 28 | redirect_to edit_user_portfolio_path(current_user, @portfolio) 29 | flash[:notice] = 'Portfolio updated successfully' 30 | else 31 | flash[:alert] = helpers.display_errors(@portfolio) 32 | render 'edit' 33 | end 34 | end 35 | 36 | def destroy 37 | @portfolio.destroy 38 | redirect_to root_path 39 | end 40 | 41 | private 42 | 43 | def set_dashboard 44 | @dashboard = 'portfolios' 45 | end 46 | 47 | def confirm_owner 48 | return if current_user == @portfolio.user 49 | flash[:alert] = 'You are not the owner of that or portfolio' 50 | redirect_to root 51 | end 52 | 53 | def set_portfolio 54 | @portfolio = helpers.active_portfolio 55 | @portfolios = current_user.portfolios.all 56 | @portfolio_header = @portfolio.portfolio_header || PortfolioHeader.new 57 | @themes = Themes.array 58 | end 59 | 60 | def portfolio_params 61 | params.require(:portfolio).permit(:url, :theme, :color_one, :color_two, 62 | :color_three, :color_four, 63 | :font_color_one, :font_color_two, 64 | :show_cover_image, :show_avatar_image, 65 | :show_years_exp, :show_proficiency) 66 | end 67 | 68 | def default_params 69 | { theme: 'default', 70 | color_one: '#0a0d72', color_two: '#83c9f4', 71 | color_three: '#2196f3', color_four: '#00a6fb', 72 | font_color_one: '#ffffff', font_color_two: '#ffffff', 73 | show_cover_image: false, show_avatar_image: true, 74 | show_years_exp: true, show_proficiency: true } 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /app/controllers/dashboard/projects_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::ProjectsController < Dashboard::PortfoliosController 2 | before_action :set_record, only: %i[update destroy edit create show] 3 | before_action :set_new_record, only: %i[index new] 4 | before_action :confirm_owner, only: %i[create update destroy] 5 | 6 | def index 7 | render 'new' 8 | end 9 | 10 | def show 11 | render 'edit' 12 | end 13 | 14 | def new; end 15 | 16 | def edit; end 17 | 18 | def create 19 | if @project.save 20 | flash[:notice] = 'Project successfully added' 21 | redirect_to portfolio_projects_path(@portfolio) 22 | else 23 | flash[:alert] = helpers.display_errors(@project) 24 | render 'new' 25 | end 26 | end 27 | 28 | def update 29 | if @project.update(project_params) 30 | flash[:notice] = 'Project successfully updated' 31 | redirect_to portfolio_projects_path(@portfolio) 32 | else 33 | flash[:alert] = helpers.display_errors(@project) 34 | render 'edit' 35 | end 36 | end 37 | 38 | def destroy 39 | @project.destroy 40 | redirect_to portfolio_projects_path(@portfolio) 41 | end 42 | 43 | private 44 | 45 | def confirm_owner 46 | return if current_user == @project.portfolio.user 47 | flash[:alert] = 'You are not the owner of that or portfolio' 48 | redirect_to root 49 | end 50 | 51 | def set_new_record 52 | @projects = @portfolio.projects.all 53 | @project = Project.new 54 | end 55 | 56 | def set_record 57 | @project = params[:id] ? Project.find(params[:id]) : @portfolio.projects.new(project_params) 58 | @projects = @portfolio.projects.all 59 | end 60 | 61 | def project_params 62 | params.require(:project).permit(:references, :title, :link, :description, 63 | :image, :tech, :role, :order) 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /app/controllers/dashboard/technologies_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::TechnologiesController < Dashboard::PortfoliosController 2 | before_action :set_record, only: %i[update destroy edit create show] 3 | before_action :set_new_record, only: %i[index new] 4 | before_action :confirm_owner, only: %i[create update destroy] 5 | 6 | def index 7 | render @portfolio.technologies.first ? 'edit' : 'new' 8 | end 9 | 10 | def show 11 | render 'edit' 12 | end 13 | 14 | def new; end 15 | 16 | def edit; end 17 | 18 | def create 19 | if @technology.save 20 | flash[:notice] = 'Technology successfully added' 21 | redirect_to portfolio_technologies_path(@portfolio) 22 | else 23 | flash[:alert] = helpers.display_errors(@technology) 24 | render 'new' 25 | end 26 | end 27 | 28 | def update 29 | if @technology.update(technology_params) 30 | flash[:notice] = 'Technology successfully updated' 31 | redirect_to portfolio_technologies_path(@portfolio) 32 | else 33 | flash[:alert] = helpers.display_errors(@technology) 34 | render 'edit' 35 | end 36 | end 37 | 38 | def destroy 39 | @technology.destroy 40 | redirect_to portfolio_technologies_path(@portfolio) 41 | end 42 | 43 | private 44 | 45 | def confirm_owner 46 | return if current_user == @technology.portfolio.user 47 | flash[:alert] = 'You are not the owner of that or portfolio' 48 | redirect_to root 49 | end 50 | 51 | def set_record 52 | @technology = params[:id] ? Technology.find(params[:id]) : @portfolio.technologies.new(technology_params) 53 | @technologies = @portfolio.technologies.all 54 | end 55 | 56 | def set_new_record 57 | @technology = Technology.new 58 | @technologies = @portfolio.technologies.all 59 | end 60 | 61 | def technology_params 62 | params.require(:technology).permit(:name, :years_exp, :proficiency) 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /app/controllers/dashboard/users_controller.rb: -------------------------------------------------------------------------------- 1 | class Dashboard::UsersController < ApplicationController 2 | before_action :authenticate_user! 3 | 4 | def update 5 | @user = current_user 6 | @user.options[:active_portfolio_id] = params[:id] 7 | @active_portfolio_url = Portfolio.find(@user.options[:active_portfolio_id]).url 8 | if @user.save 9 | flash[:notice] = "Active portfolio changed to #{@active_portfolio_url}" 10 | else 11 | flash[:alert] = 'Doh! Something went wrong...' 12 | end 13 | 14 | if request.referrer.split('/')[3] == 'preview' 15 | redirect_to "/preview/#{@active_portfolio_url}" 16 | else 17 | redirect_to request.referrer 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/controllers/front_end/portfolio_controller.rb: -------------------------------------------------------------------------------- 1 | class FrontEnd::PortfolioController < ApplicationController 2 | layout 'dashboard', only: [:preview] 3 | rescue_from Exception, :with => :render_404 4 | 5 | def show 6 | render_portfolio 7 | end 8 | 9 | def preview 10 | render_portfolio 11 | @portfolios = current_user.portfolios.all 12 | @dashboard = 'portfolios' 13 | render 'dashboard/portfolios/preview' 14 | end 15 | 16 | private 17 | 18 | def render_portfolio 19 | @portfolio = Portfolio.find_by(url: params[:portfolio]) 20 | @portfolio_header = @portfolio.portfolio_header || filler_header 21 | @projects = @portfolio.projects.all.order(:order) 22 | @technologies = @portfolio.technologies.all 23 | @about = @portfolio.about || filler_about 24 | @first_name = @portfolio_header.header_one.split(' ').first rescue '' 25 | 26 | if @portfolio.show_years_exp && @portfolio.show_proficiency 27 | @show_technology = 'all' 28 | elsif @portfolio.show_years_exp 29 | @show_technology = 'years' 30 | elsif @portfolio.show_proficiency 31 | @show_technology = 'proficiency' 32 | else 33 | @show_technology = 'none' 34 | end 35 | end 36 | 37 | def render_404 38 | flash[:alert] = 'This Portfolio does not exist' 39 | redirect_to root_path 40 | end 41 | 42 | def filler_about 43 | About.new( 44 | about_me: "Go back to your dashboard and create your 'About Me'", 45 | email: '', 46 | github: '', 47 | linkedin: '', 48 | facebook: '', 49 | twitter: '', 50 | website: '', 51 | about_me_brief: '' 52 | ) 53 | end 54 | 55 | def filler_header 56 | PortfolioHeader.new( 57 | header_one: "Go back to your dashboard and create your 'Portfolio Header'", 58 | header_two: '', 59 | header_one_color: '#000000', 60 | header_two_color: '#000000' 61 | ) 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | redirect_to user_dashboard_index_path(current_user) if current_user 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/users/confirmations_controller.rb: -------------------------------------------------------------------------------- 1 | class Users::ConfirmationsController < Devise::ConfirmationsController 2 | # GET /resource/confirmation/new 3 | # def new 4 | # super 5 | # end 6 | 7 | # POST /resource/confirmation 8 | # def create 9 | # super 10 | # end 11 | 12 | # GET /resource/confirmation?confirmation_token=abcdef 13 | # def show 14 | # super 15 | # end 16 | 17 | # protected 18 | 19 | # The path used after resending confirmation instructions. 20 | # def after_resending_confirmation_instructions_path_for(resource_name) 21 | # super(resource_name) 22 | # end 23 | 24 | # The path used after confirmation. 25 | # def after_confirmation_path_for(resource_name, resource) 26 | # super(resource_name, resource) 27 | # end 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/users/omniauth_callbacks_controller.rb: -------------------------------------------------------------------------------- 1 | class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 2 | # You should configure your model like this: 3 | # devise :omniauthable, omniauth_providers: [:twitter] 4 | 5 | # You should also create an action method in this controller like this: 6 | # def twitter 7 | # end 8 | 9 | # More info at: 10 | # https://github.com/plataformatec/devise#omniauth 11 | 12 | # GET|POST /resource/auth/twitter 13 | # def passthru 14 | # super 15 | # end 16 | 17 | # GET|POST /users/auth/twitter/callback 18 | # def failure 19 | # super 20 | # end 21 | 22 | # protected 23 | 24 | # The path used when OmniAuth fails 25 | # def after_omniauth_failure_path_for(scope) 26 | # super(scope) 27 | # end 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/users/passwords_controller.rb: -------------------------------------------------------------------------------- 1 | class Users::PasswordsController < Devise::PasswordsController 2 | # GET /resource/password/new 3 | # def new 4 | # super 5 | # end 6 | 7 | # POST /resource/password 8 | # def create 9 | # super 10 | # end 11 | 12 | # GET /resource/password/edit?reset_password_token=abcdef 13 | # def edit 14 | # super 15 | # end 16 | 17 | # PUT /resource/password 18 | # def update 19 | # super 20 | # end 21 | 22 | # protected 23 | 24 | # def after_resetting_password_path_for(resource) 25 | # super(resource) 26 | # end 27 | 28 | # The path used after sending reset password instructions 29 | # def after_sending_reset_password_instructions_path_for(resource_name) 30 | # super(resource_name) 31 | # end 32 | end 33 | -------------------------------------------------------------------------------- /app/controllers/users/registrations_controller.rb: -------------------------------------------------------------------------------- 1 | class Users::RegistrationsController < Devise::RegistrationsController 2 | # before_action :configure_sign_up_params, only: [:create] 3 | # before_action :configure_account_update_params, only: [:update] 4 | 5 | # GET /resource/sign_up 6 | # def new 7 | # super 8 | # end 9 | 10 | # POST /resource 11 | # def create 12 | # super 13 | # end 14 | 15 | # GET /resource/edit 16 | # def edit 17 | # super 18 | # end 19 | 20 | # PUT /resource 21 | # def update 22 | # super 23 | # end 24 | 25 | # DELETE /resource 26 | # def destroy 27 | # super 28 | # end 29 | 30 | # GET /resource/cancel 31 | # Forces the session data which is usually expired after sign 32 | # in to be expired now. This is useful if the user wants to 33 | # cancel oauth signing in/up in the middle of the process, 34 | # removing all OAuth session data. 35 | # def cancel 36 | # super 37 | # end 38 | 39 | # protected 40 | 41 | # If you have extra params to permit, append them to the sanitizer. 42 | # def configure_sign_up_params 43 | # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) 44 | # end 45 | 46 | # If you have extra params to permit, append them to the sanitizer. 47 | # def configure_account_update_params 48 | # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) 49 | # end 50 | 51 | # The path used after sign up. 52 | def after_sign_up_path_for(resource) 53 | user_email = current_user.email.split('@').first 54 | url = generate_unique_url(user_email) 55 | default = { url: url, theme: 'default', 56 | color_one: '#0a0d72', color_two: '#83c9f4', 57 | color_three: '#2196f3', color_four: '#00a6fb', 58 | font_color_one: '#ffffff', font_color_two: '#ffffff', 59 | show_cover_image: false, show_avatar_image: true, 60 | show_years_exp: true, show_proficiency: true } 61 | portfolio = current_user.portfolios.create(default) 62 | current_user.update_attribute(:options, active_portfolio_id: portfolio.id) 63 | current_user.save 64 | root_path 65 | end 66 | 67 | # The path used after sign up for inactive accounts. 68 | # def after_inactive_sign_up_path_for(resource) 69 | # super(resource) 70 | # end 71 | 72 | private 73 | 74 | def generate_unique_url(user_email) 75 | url = "#{user_email}#{rand(10**10).to_s.rjust(10, '0')}" 76 | Portfolio.exists?(url: url) ? generate_unique_url(user_email) : url 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /app/controllers/users/sessions_controller.rb: -------------------------------------------------------------------------------- 1 | class Users::SessionsController < Devise::SessionsController 2 | # before_action :configure_sign_in_params, only: [:create] 3 | 4 | # GET /resource/sign_in 5 | # def new 6 | # super 7 | # end 8 | 9 | # POST /resource/sign_in 10 | # def create 11 | # super 12 | # end 13 | 14 | # DELETE /resource/sign_out 15 | # def destroy 16 | # super 17 | # end 18 | 19 | # protected 20 | 21 | # If you have extra params to permit, append them to the sanitizer. 22 | # def configure_sign_in_params 23 | # devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute]) 24 | # end 25 | end 26 | -------------------------------------------------------------------------------- /app/controllers/users/unlocks_controller.rb: -------------------------------------------------------------------------------- 1 | class Users::UnlocksController < Devise::UnlocksController 2 | # GET /resource/unlock/new 3 | # def new 4 | # super 5 | # end 6 | 7 | # POST /resource/unlock 8 | # def create 9 | # super 10 | # end 11 | 12 | # GET /resource/unlock?unlock_token=abcdef 13 | # def show 14 | # super 15 | # end 16 | 17 | # protected 18 | 19 | # The path used after sending unlock password instructions 20 | # def after_sending_unlock_instructions_path_for(resource) 21 | # super(resource) 22 | # end 23 | 24 | # The path used after unlocking the resource 25 | # def after_unlock_path_for(resource) 26 | # super(resource) 27 | # end 28 | end 29 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def display_errors(record) 3 | record.errors.full_messages.each{|msg| msg}.join("
").html_safe 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/helpers/dashboard_helper.rb: -------------------------------------------------------------------------------- 1 | module DashboardHelper 2 | def active_portfolio 3 | Portfolio.find(current_user.options[:active_portfolio_id]) rescue current_user.portfolios.first 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /app/models/about.rb: -------------------------------------------------------------------------------- 1 | class About < ApplicationRecord 2 | belongs_to :portfolio 3 | validates :location, :email, :github, :linkedin, :twitter, :facebook, :website, 4 | length: { maximum: 100 } 5 | validates :about_me_brief, length: { maximum: 150 } 6 | validates :about_me, length: { maximum: 2000 } 7 | validates :github, :linkedin, :facebook, :twitter, :website, url: true 8 | end 9 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/models/portfolio.rb: -------------------------------------------------------------------------------- 1 | class Portfolio < ApplicationRecord 2 | validates :url, presence: true, 3 | length: { in: 3..30 }, 4 | uniqueness: true 5 | validates_format_of :url, with: /\A[-a-z0-9_]+\z/, 6 | message: 'must only contain lowercase alphanumeric characters, hyphens, or underscores' 7 | validates :color_one, :color_two, :color_three, :color_four, :font_color_one, :font_color_two, 8 | css_hex_color: true 9 | validates :theme, inclusion: { in: Themes.array } 10 | belongs_to :user 11 | has_many :projects, dependent: :delete_all 12 | has_many :technologies, dependent: :delete_all 13 | has_one :portfolio_header, dependent: :delete 14 | has_one :about, dependent: :delete 15 | end 16 | -------------------------------------------------------------------------------- /app/models/portfolio_header.rb: -------------------------------------------------------------------------------- 1 | class PortfolioHeader < ApplicationRecord 2 | belongs_to :portfolio 3 | validates :header_one_color, :header_two_color, 4 | css_hex_color: true 5 | validates :header_one, :header_two, length: 6 | { maximum: 100 } 7 | mount_uploader :cover_image, CoverImageUploader 8 | mount_uploader :avatar_image, AvatarImageUploader 9 | end 10 | -------------------------------------------------------------------------------- /app/models/project.rb: -------------------------------------------------------------------------------- 1 | class Project < ApplicationRecord 2 | belongs_to :portfolio 3 | validates :link, :role, length: { maximum: 200 } 4 | validates :tech, length: { maximum: 500 } 5 | validates :description, length: { maximum: 2000 } 6 | validates :order, numericality: { only_integer: true, greater_than: 0, less_than: 20 } 7 | validates :title, length: { minimum: 1, maximum: 40 } 8 | validates :portfolio_id, max_projects: true 9 | mount_uploader :image, ImageUploader 10 | end 11 | -------------------------------------------------------------------------------- /app/models/technology.rb: -------------------------------------------------------------------------------- 1 | class Technology < ApplicationRecord 2 | validates :proficiency, 3 | numericality: { greater_than: 0, less_than: 11 } 4 | validates :years_exp, 5 | numericality: { greater_than_or_equal_to: 0 } 6 | validates :name, 7 | presence: true, 8 | length: { maximum: 20 } 9 | belongs_to :portfolio 10 | end 11 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ApplicationRecord 2 | store :options, accessors: %i[active_portfolio_id blog_active?] 3 | has_many :portfolios, dependent: :destroy 4 | has_many :job_applications, dependent: :destroy 5 | include Gravtastic 6 | gravtastic size: 60, filetype: 'gif' 7 | # Include default devise modules. Others available are: 8 | # :confirmable, :lockable, :timeoutable and :omniauthable 9 | devise :database_authenticatable, :registerable, 10 | :recoverable, :rememberable, :trackable, :validatable 11 | end 12 | -------------------------------------------------------------------------------- /app/uploaders/avatar_image_uploader.rb: -------------------------------------------------------------------------------- 1 | class AvatarImageUploader < CarrierWave::Uploader::Base 2 | 3 | # Include RMagick or MiniMagick support: 4 | # include CarrierWave::RMagick 5 | include CarrierWave::MiniMagick 6 | 7 | # Choose what kind of storage to use for this uploader: 8 | storage :fog 9 | # storage :fog 10 | 11 | # Override the directory where uploaded files will be stored. 12 | # This is a sensible default for uploaders that are meant to be mounted: 13 | def store_dir 14 | "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 15 | end 16 | 17 | # Provide a default URL as a default if there hasn't been a file uploaded: 18 | # def default_url(*args) 19 | # # For Rails 3.1+ asset pipeline compatibility: 20 | # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 21 | # 22 | # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 23 | # end 24 | 25 | # Process files as they are uploaded: 26 | # process scale: [230, 280] 27 | # 28 | # def scale(width, height) 29 | # # do something 30 | # end 31 | 32 | # Create different versions of your uploaded files: 33 | version :full do 34 | process resize_to_fit: [225, 300], quality: 100 35 | end 36 | 37 | version :preview do 38 | process resize_to_fit: [66, 88], quality: 50 39 | end 40 | 41 | # Add a white list of extensions which are allowed to be uploaded. 42 | # For images you might use something like this: 43 | def extension_whitelist 44 | %w(jpg jpeg gif png) 45 | end 46 | 47 | # Override the filename of the uploaded files: 48 | # Avoid using model.id or version_name here, see uploader/store.rb for details. 49 | # def filename 50 | # "something.jpg" if original_filename 51 | # end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /app/uploaders/cover_image_uploader.rb: -------------------------------------------------------------------------------- 1 | class CoverImageUploader < CarrierWave::Uploader::Base 2 | 3 | # Include RMagick or MiniMagick support: 4 | # include CarrierWave::RMagick 5 | include CarrierWave::MiniMagick 6 | 7 | # Choose what kind of storage to use for this uploader: 8 | storage :fog 9 | # storage :fog 10 | 11 | # Override the directory where uploaded files will be stored. 12 | # This is a sensible default for uploaders that are meant to be mounted: 13 | def store_dir 14 | "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 15 | end 16 | 17 | # Provide a default URL as a default if there hasn't been a file uploaded: 18 | # def default_url(*args) 19 | # # For Rails 3.1+ asset pipeline compatibility: 20 | # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 21 | # 22 | # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 23 | # end 24 | 25 | # Process files as they are uploaded: 26 | # process scale: [1920, 800] 27 | # 28 | # def scale(width, height) 29 | # # do something 30 | # end 31 | 32 | # Create different versions of your uploaded files: 33 | version :full do 34 | process resize_to_fit: [10000, 800], quality: 100 35 | end 36 | 37 | version :preview do 38 | process resize_to_fit: [10000, 229], quality: 50 39 | end 40 | 41 | # Add a white list of extensions which are allowed to be uploaded. 42 | # For images you might use something like this: 43 | def extension_whitelist 44 | %w(jpg jpeg gif png) 45 | end 46 | 47 | # Override the filename of the uploaded files: 48 | # Avoid using model.id or version_name here, see uploader/store.rb for details. 49 | # def filename 50 | # "something.jpg" if original_filename 51 | # end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /app/uploaders/image_uploader.rb: -------------------------------------------------------------------------------- 1 | class ImageUploader < CarrierWave::Uploader::Base 2 | 3 | # Include RMagick or MiniMagick support: 4 | # include CarrierWave::RMagick 5 | include CarrierWave::MiniMagick 6 | 7 | # Choose what kind of storage to use for this uploader: 8 | storage :fog 9 | # storage :fog 10 | 11 | # Override the directory where uploaded files will be stored. 12 | # This is a sensible default for uploaders that are meant to be mounted: 13 | def store_dir 14 | "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 15 | end 16 | 17 | # Provide a default URL as a default if there hasn't been a file uploaded: 18 | # def default_url(*args) 19 | # # For Rails 3.1+ asset pipeline compatibility: 20 | # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 21 | # 22 | # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 23 | # end 24 | 25 | # Process files as they are uploaded: 26 | # process scale: [200, 300] 27 | # 28 | # def scale(width, height) 29 | # # do something 30 | # end 31 | 32 | # Create different versions of your uploaded files: 33 | process quality: 100 34 | 35 | version :thumb do 36 | process resize_to_fit: [110, 110], quality: 50 37 | end 38 | 39 | version :large do 40 | process resize_to_fit: [10000, 600], quality: 100 41 | end 42 | 43 | version :small do 44 | process resize_to_fit: [10000, 150], quality: 100 45 | end 46 | 47 | # Add a white list of extensions which are allowed to be uploaded. 48 | # For images you might use something like this: 49 | def extension_whitelist 50 | %w(jpg jpeg gif png) 51 | end 52 | 53 | # Override the filename of the uploaded files: 54 | # Avoid using model.id or version_name here, see uploader/store.rb for details. 55 | # def filename 56 | # "something.jpg" if original_filename 57 | # end 58 | 59 | end 60 | -------------------------------------------------------------------------------- /app/validators/css_hex_color_validator.rb: -------------------------------------------------------------------------------- 1 | class CssHexColorValidator < ActiveModel::EachValidator 2 | def validate_each(object, attribute, value) 3 | unless value =~ /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i 4 | object.errors[attribute] << (options[:message] || 'must be a valid CSS hex color code') 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/validators/max_projects_validator.rb: -------------------------------------------------------------------------------- 1 | class MaxProjectsValidator < ActiveModel::EachValidator 2 | def validate_each(object, attribute, value) 3 | unless Portfolio.find(value).projects.count < 10 4 | object.errors[attribute] << (options[:message] || 'You have reached the maximum number of allowed projects for this portfolio') 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/validators/url_validator.rb: -------------------------------------------------------------------------------- 1 | class UrlValidator < ActiveModel::EachValidator 2 | def validate_each(record, attribute, value) 3 | record.errors[attribute] << (options[:message] || "must be a valid URL (URLs must start with 'http://')") unless value == '' || url_valid?(value) 4 | end 5 | 6 | # a URL may be technically well-formed but may 7 | # not actually be valid, so this checks for both. 8 | def url_valid?(url) 9 | url = URI.parse(url) rescue false 10 | url.is_a?(URI::HTTP) || url.is_a?(URI::HTTPS) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/dashboard/abouts/_form.html.haml: -------------------------------------------------------------------------------- 1 | = form_for [@portfolio, @about] do |f| 2 | .form-about 3 | .field 4 | = f.label :location 5 | %br 6 | = f.text_field :location 7 | .field 8 | = f.label :email 9 | %br 10 | = f.text_field :email 11 | .field 12 | = f.label :github 13 | %br 14 | = f.text_field :github 15 | .field 16 | = f.label :linkedin 17 | %br 18 | = f.text_field :linkedin 19 | .field 20 | = f.label :facebook 21 | %br 22 | = f.text_field :facebook 23 | .field 24 | = f.label :twitter 25 | %br 26 | = f.text_field :twitter 27 | .field 28 | = f.label :website 29 | %br 30 | = f.text_field :website 31 | .field 32 | = f.label :abbreviated_about_me 33 | %br 34 | = f.text_area :about_me_brief, class: 'about-me-brief-input' 35 | .field.about-me 36 | = f.label :about_me 37 | %br 38 | = f.text_area :about_me, class: 'about-me-input' 39 | .actions 40 | = f.submit 'Update', class: 'update-button' 41 | -------------------------------------------------------------------------------- /app/views/dashboard/abouts/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: 'dashboard/dashboard/select_active_portfolio' 2 | .about-main 3 | .about-form 4 | %h4 Edit Your "About Me" 5 | .about-form-container 6 | = render partial: 'form' 7 | -------------------------------------------------------------------------------- /app/views/dashboard/abouts/new.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: 'dashboard/dashboard/select_active_portfolio' 2 | .about-main 3 | .about-form 4 | %h4 Create Your "About Me" 5 | .about-form-container 6 | %p 7 | This is where you can fill out your personal information to be displayed 8 | on your portfolio. Be sure to use full links for your contact info (eg: 9 | links should begin with 'http://') 10 | = render partial: 'form' 11 | -------------------------------------------------------------------------------- /app/views/dashboard/blogs/show.html.haml: -------------------------------------------------------------------------------- 1 | %h2.place-holder 2 | This is a planned feature. Check out the 3 | = link_to 'repository', 'https://github.com/SWLivingstone/my_dev_portal' 4 | for updates or to help out! 5 | -------------------------------------------------------------------------------- /app/views/dashboard/dashboard/_select_active_portfolio.html.haml: -------------------------------------------------------------------------------- 1 | .set-portfolio-container 2 | = form_for current_user do |f| 3 | .form-set-portfolio 4 | .field 5 | = f.label :active_portfolio 6 | = f.select :options, @portfolios.map { |portfolio| [ portfolio.url, portfolio.id]}, selected: [ @portfolio.url, @portfolio.id ] 7 | -------------------------------------------------------------------------------- /app/views/dashboard/dashboard/index.html.haml: -------------------------------------------------------------------------------- 1 | .home-container 2 | .welcome-box 3 | .go-to-portfolio 4 | = link_to 'View Your Portfolio', "/#{@portfolio.url}" 5 | - if @new_user 6 | .new-user-box-container 7 | %h2 Welcome to Your Dev Portal! 8 | .new-user-box 9 | %p Use the sidebar to navigate to the various components of your portfolio. You can then change settings, upload photos, and add information. 10 | %p 11 | %b Finish filling out your portoflio. Check the list below to see what still needs to be done! 12 | - unless @about.about_me 13 | %p 14 | Be sure to fill out your 'About Me' 15 | = link_to 'HERE', portfolio_abouts_path(@portfolio) 16 | - unless @projects.count > 0 17 | %p 18 | Add projects to your portfolio 19 | = link_to 'HERE', portfolio_projects_path(@portfolio) 20 | - unless @technologies.count > 0 21 | %p 22 | Add skills and technology that you know 23 | = link_to 'HERE', portfolio_technologies_path(@portfolio) 24 | - unless @portfolio_header.header_one 25 | %p 26 | Create your Portfolio Header 27 | = link_to 'HERE', portfolio_portfolio_headers_path(@portfolio) 28 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/_applications_list.html.haml: -------------------------------------------------------------------------------- 1 | .grid-header 2 | .export-csv 3 | = link_to 'Export CSV', user_job_applications_path(current_user, format: :csv), type: 'button', class: 'export-button' 4 | .application-count 5 | = "Showing #{@job_applications.count} of #{current_user.job_applications.count} Job Applications" 6 | .table-container{ id: 'filterrific_results' } 7 | %table.table.table-striped.table-dark.table-responsive 8 | %thead 9 | %tr.table-heading 10 | %th{ scope: 'col', style: 'width: 120px;'} Options 11 | %th{ scope: 'col' } First contact date 12 | %th{ scope: 'col' } Company name 13 | %th{ scope: 'col' } Job location 14 | %th{ scope: 'col' } Enthusiasm 15 | %th{ scope: 'col' } Job title 16 | %th{ scope: 'col' } Referral 17 | %th{ scope: 'col' } Referral type 18 | %th{ scope: 'col' } Status 19 | %th.last-col{ scope: 'col' } Industry 20 | %tbody 21 | - job_applications.each do |job_application| 22 | %tr 23 | %th{ scope: 'row' } 24 | .table-item-options 25 | = link_to user_job_application_path(current_user, job_application) do 26 | .job-application-icon.view{ 'data-placement' => 'right', title: 'View Application' } 27 | = link_to edit_user_job_application_path(current_user, job_application) do 28 | .job-application-icon.edit{ 'data-placement' => 'right', title: 'Edit Application' } 29 | = link_to user_job_application_path(current_user, job_application), method: :delete, data: { confirm: 'Are you sure that you would like to delete this Application?' } do 30 | .job-application-icon.delete{ 'data-placement' => 'right', title: 'Delete Application' } 31 | %td= job_application.first_contact_date 32 | %td= job_application.company_name 33 | %td= job_application.job_location 34 | %td= job_application.enthusiasm 35 | %td= job_application.job_title 36 | %td= job_application.referral 37 | %td= job_application.referral_type 38 | %td= job_application.status 39 | %td.last-col= job_application.industry 40 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/_form.html.haml: -------------------------------------------------------------------------------- 1 | = form_for [current_user, @job_application] do |f| 2 | -# - if job_application.errors.any? 3 | -# #error_explanation 4 | -# %h2= "#{pluralize(job_application.errors.count, "error")} prohibited this job_application from being saved:" 5 | -# %ul 6 | -# - @job_application.errors.full_messages.each do |message| 7 | -# %li= message 8 | 9 | 10 | .field 11 | = f.label :industry 12 | = f.text_field :industry 13 | .field 14 | = f.label :company_name 15 | = f.text_field :company_name 16 | .field 17 | = f.label :company_website 18 | = f.text_field :company_website 19 | .field 20 | = f.label :job_location 21 | = f.text_field :job_location 22 | .field 23 | = f.label :job_title 24 | = f.text_field :job_title 25 | .field 26 | = f.label :job_posting_link 27 | = f.text_field :job_link 28 | .field 29 | = f.label 'Referral site/person' 30 | = f.text_field :referral 31 | .field.notes 32 | = f.label :notes 33 | %br 34 | = f.text_area :notes 35 | .field 36 | = f.label :referral_type 37 | = f.select :referral_type, ['cold outreach', 'mentor', 'personal connection', 'new connection', 'career website'], selected: @job_application.referral_type || 'career website' 38 | .field 39 | = f.label :first_contact_date 40 | %br 41 | = f.date_select :first_contact_date 42 | .status-enthusiasm 43 | .field 44 | = f.label :status 45 | %br 46 | = f.select :status, %w[researching applied interviewing rejected offer], selected: @job_application.status || 'applied' 47 | .field.enthusiasm 48 | = f.label :enthusiasm 49 | %br 50 | = f.select :enthusiasm, %w[high medium low], selected: @job_application.enthusiasm || 'high' 51 | .actions 52 | = f.submit "#{@job_application.persisted? ? 'Submit Changes' : 'Add Job Application'}" 53 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/edit.html.haml: -------------------------------------------------------------------------------- 1 | .new-application-main 2 | .edit-item-options 3 | = link_to user_job_applications_path(current_user) do 4 | .job-application-icon.back{ 'data-placement' => 'right', title: 'Go Back' } 5 | = link_to user_job_application_path(current_user, @job_application), method: :delete, data: { confirm: 'Are you sure that you would like to delete this Application?' } do 6 | .job-application-icon.delete{ 'data-placement' => 'right', title: 'Delete Application' } 7 | .job-application-form-container 8 | .form-job-application 9 | %h1 Edit Job Application 10 | 11 | = render 'form' 12 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/index.csv.erb: -------------------------------------------------------------------------------- 1 | <%- headers = %w[first_contact_date company_name company_website job_location 2 | enthusiasm job_title job_link referral referral_type status 3 | industry notes] %> 4 | <%= CSV.generate_line headers %> 5 | <%- @job_applications.each do |entry| %> 6 | <%= CSV.generate_line([entry.first_contact_date, entry.company_name, entry.company_website, 7 | entry.job_location, entry.enthusiasm, entry.job_title, 8 | entry.job_link, entry.referral, entry.referral_type, 9 | entry.status, entry.industry, entry.notes]).html_safe %> 10 | <%- end %> 11 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/index.html.haml: -------------------------------------------------------------------------------- 1 | .show-main 2 | #filter-expand-button.hidden 3 | .arrow-icon.right 4 | .filter-search-box 5 | #filter-collapse-button 6 | %h3 Filters 7 | .arrow-icon.left 8 | = form_for_filterrific @filterrific, remote: true do |f| 9 | .search-filter.search 10 | .label 11 | Search 12 | = f.text_field :search_query, 13 | class: 'filterrific-periodically-observed job-application-search' 14 | .search-filter.sorted-by 15 | .label 16 | Sorted By 17 | = f.select :asc_desc, @filterrific.select_options[:asc_desc] 18 | = f.select :sorted_by, @filterrific.select_options[:sorted_by] 19 | %h5 Filtered by: 20 | .search-filter.filter-by 21 | .label 22 | Enthusiasm 23 | = f.select :enthusiasm, @filterrific.select_options[:enthusiasm] 24 | .search-filter.filter-by 25 | .label 26 | Application Status 27 | = f.select :status, @filterrific.select_options[:status] 28 | .search-filter.filter-by 29 | .label 30 | Referral Type 31 | = f.select :referral_type, @filterrific.select_options[:referral_type] 32 | .search-filter.first-contact-date 33 | .label 34 | First Contact Date 35 | %h6 Between 36 | = f.date_select :before, { selected: 1.days.from_now } 37 | %h6 and 38 | = f.date_select :after, { selected: 1.years.ago } 39 | .reset-filter 40 | = link_to 'Reset Filters', reset_filterrific_url, type: 'button', class: 'reset-button' 41 | = render_filterrific_spinner 42 | .application-grid-container 43 | .add-application-button 44 | = link_to new_user_job_application_path(current_user) do 45 | .add-application-icon{ 'data-placement' => 'right', title: 'Add New Application' } 46 | Add New 47 | .job-application-container 48 | #application-list-table 49 | = render partial: 'applications_list', locals: { job_applications: @job_applications } 50 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/index.js.erb: -------------------------------------------------------------------------------- 1 | $('#application-list-table').html( 2 | "<%= escape_javascript(render(partial: 'applications_list', locals: { job_applications: @job_applications })) %>" 3 | ) 4 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/new.html.haml: -------------------------------------------------------------------------------- 1 | .new-application-main 2 | .new-item-options 3 | = link_to user_job_applications_path(current_user) do 4 | .job-application-icon.back{ 'data-placement' => 'right', title: 'Go Back' } 5 | .job-application-form-container 6 | .form-job-application 7 | %h1 New Job Application 8 | 9 | = render 'form' 10 | -------------------------------------------------------------------------------- /app/views/dashboard/job_applications/show.html.haml: -------------------------------------------------------------------------------- 1 | .show-application-main 2 | .show-item-options 3 | = link_to user_job_applications_path(current_user) do 4 | .job-application-icon.back{ 'data-placement' => 'right', title: 'Go Back' } 5 | = link_to edit_user_job_application_path(current_user, @job_application) do 6 | .job-application-icon.edit{ 'data-placement' => 'right', title: 'Edit Application' } 7 | = link_to user_job_application_path(current_user, @job_application), method: :delete, data: { confirm: 'Are you sure that you would like to delete this Application?' } do 8 | .job-application-icon.delete{ 'data-placement' => 'right', title: 'Delete Application' } 9 | .show-application-container 10 | .show-application 11 | %p 12 | %b First contact date: 13 | %br 14 | = @job_application.first_contact_date 15 | %p 16 | %b Enthusiasm: 17 | = @job_application.enthusiasm 18 | %br 19 | %b Status: 20 | = @job_application.status 21 | %p 22 | %b Company name: 23 | %br 24 | = @job_application.company_name 25 | %p 26 | %b Job location: 27 | %br 28 | = @job_application.job_location 29 | %p 30 | %b Job title: 31 | %br 32 | = @job_application.job_title 33 | %p 34 | %b Referral: 35 | %br 36 | = @job_application.referral 37 | %p 38 | %b Referral type: 39 | %br 40 | = @job_application.referral_type 41 | %p 42 | %b Industry: 43 | %br 44 | = @job_application.industry 45 | %p.link 46 | %b Job link: 47 | %br 48 | = @job_application.job_link 49 | %p.link 50 | %b Company website: 51 | %br 52 | = @job_application.company_website 53 | %p.notes 54 | %b Notes: 55 | = @job_application.notes 56 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolio_headers/_form.html.haml: -------------------------------------------------------------------------------- 1 | -# Inline script required to load minicolors() without refresh 2 | :javascript 3 | $('.color-picker').minicolors() 4 | = form_for [@portfolio, @portfolio_header] do |f| 5 | .form-portfolio-header 6 | .field 7 | = f.label :header_one 8 | %br 9 | = f.text_field :header_one 10 | .field 11 | = f.label :header_one_font_color 12 | %br 13 | = f.text_field :header_one_color, as: :minicolors, class: 'color-picker' 14 | .field 15 | = f.label :header_two 16 | %br 17 | = f.text_field :header_two 18 | .field 19 | = f.label :header_two_font_color 20 | %br 21 | = f.text_field :header_two_color, as: :minicolors, class: 'color-picker' 22 | .field.upload-image 23 | = f.label :cover_image 24 | %small Prefered resolution 1290x800 (12:5 aspect ratio) 25 | %br 26 | = f.file_field :cover_image, class: 'form-project-image' 27 | .field.upload-image 28 | = f.label :avatar_image 29 | %small Prefered resolution 225x300 (3:4 aspect ratio) 30 | %br 31 | = f.file_field :avatar_image, class: 'form-project-image' 32 | .actions 33 | = f.submit 'Update Your Portfolio Header' 34 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolio_headers/_show.html.haml: -------------------------------------------------------------------------------- 1 | .portfolio-header-preview{ style: "background-image: url(#{@portfolio_header.cover_image.preview.url})" } 2 | .preview-avatar 3 | %img.preview-avatar-image{ src: "#{@portfolio_header.avatar_image.preview.url}"} 4 | .preview-header-one{ style: "color: #{@portfolio_header.header_one_color}" } 5 | = @portfolio_header.header_one 6 | .preview-header-two{ style: "color: #{@portfolio_header.header_two_color}" } 7 | = @portfolio_header.header_two 8 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolio_headers/edit.html.haml: -------------------------------------------------------------------------------- 1 | .portfolio-header-main 2 | .portfolio-header-form 3 | %h4 Edit Your Portfolio Header 4 | = render partial: 'form' 5 | %h3 Preview 6 | = render partial: 'show' 7 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolio_headers/new.html.haml: -------------------------------------------------------------------------------- 1 | .portfolio-header-main 2 | .portfolio-header-form 3 | %h4 Create Your Portfolio Header 4 | %p 5 | Here you can fill in the details for your portfolio's header. It is 6 | recomended that Header one be your name but of course you can make it 7 | whatever you like. 8 | %small 9 | NOTE: The preview may not be 100% acurate as your portfolio's header is 10 | largly dependent on the theme that you chose. 11 | = render partial: 'form' 12 | %h3 Preview 13 | = render partial: 'show' 14 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_colors.html.haml: -------------------------------------------------------------------------------- 1 | -# Inline script required to load minicolors() without refresh 2 | :javascript 3 | $('.color-picker').minicolors() 4 | .config-container 5 | %h4 Change Theme Colors 6 | .settings-form-container#change-theme-color 7 | = form_for [current_user, @portfolio] do |f| 8 | .form-portfolio-colors 9 | .field 10 | = f.label :color_one 11 | = f.text_field :color_one, as: :minicolors, class: 'color-picker' 12 | .field 13 | = f.label :color_two 14 | = f.text_field :color_two, as: :minicolors, class: 'color-picker' 15 | .field 16 | = f.label :color_three 17 | = f.text_field :color_three, as: :minicolors, class: 'color-picker' 18 | .field 19 | = f.label :color_four 20 | = f.text_field :color_four, as: :minicolors, class: 'color-picker' 21 | .actions 22 | = submit_tag 'Update', class: 'update-button' 23 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_display_image.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Display Images 3 | .settings-form-container#change-image-display 4 | %p Select which images will be displayed on your portfolio. What replaces the image will depend on your chosen theme. 5 | = form_for [current_user, @portfolio] do |f| 6 | .form-image-display 7 | .field 8 | = f.label :show_avatar_image 9 | = f.select :show_avatar_image, [['Yes', true], ['No', false]], selected: @portfolio.show_avatar_image 10 | .field 11 | = f.label :show_cover_image 12 | = f.select :show_cover_image, [['Yes', true], ['No', false]], selected: @portfolio.show_cover_image 13 | .actions 14 | = submit_tag 'Update', class: 'update-button' 15 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_font_colors.html.haml: -------------------------------------------------------------------------------- 1 | -# Inline script required to load minicolors() without refresh 2 | :javascript 3 | $('.color-picker').minicolors() 4 | .config-container 5 | %h4 Change Font Colors 6 | .settings-form-container#change-font-colors 7 | %p Pick the main font colors to be used for your portfolio. Note: These font colors are seperate from your header font colors 8 | = form_for [current_user, @portfolio] do |f| 9 | .form-portfolio-font-colors 10 | .field 11 | = f.label :font_color_one 12 | = f.text_field :font_color_one, as: :minicolors, class: 'color-picker' 13 | .field 14 | = f.label :font_color_two 15 | = f.text_field :font_color_two, as: :minicolors, class: 'color-picker' 16 | .actions 17 | = submit_tag 'Update', class: 'update-button' 18 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_header_font_colors.html.haml: -------------------------------------------------------------------------------- 1 | -# Inline script required to load minicolors() without refresh 2 | :javascript 3 | $('.color-picker').minicolors() 4 | .config-container 5 | %h4 Header Font Colors 6 | .settings-form-container#change-font-colors 7 | %p 8 | Pick the font colors to be used for your header text. 9 | *note* these are seperate from your theme colors 10 | = form_for [@portfolio, @portfolio_header] do |f| 11 | .form-portfolio-font-colors 12 | .field 13 | = f.label :header_one 14 | = f.text_field :header_one_color, as: :minicolors, class: 'color-picker' 15 | .field 16 | = f.label :header_two 17 | = f.text_field :header_two_color, as: :minicolors, class: 'color-picker' 18 | .actions 19 | = f.submit 'Update', class: 'update-button' 20 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_header_images.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Upload Header Images 3 | .settings-form-container#change-header-images 4 | = form_for [@portfolio, @portfolio_header] do |f| 5 | .form-header-images 6 | .field.upload-image 7 | = f.label :cover_image 8 | %br 9 | %small Prefered 1290x800 (12:5 aspect ratio) 10 | %br 11 | = f.file_field :cover_image, class: 'form-project-image' 12 | .field.upload-image 13 | = f.label :avatar_image 14 | %br 15 | %small Prefered 225x300 (3:4 aspect ratio) 16 | %br 17 | = f.file_field :avatar_image, class: 'form-project-image' 18 | .actions 19 | = f.submit 'Update', class: 'update-button' 20 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_header_text.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Header Text 3 | .settings-form-container#change-header-text 4 | = form_for [@portfolio, @portfolio_header] do |f| 5 | .form-header-text 6 | .field 7 | = f.label :header_one_ 8 | %small (A good spot for your name) 9 | = f.text_field :header_one 10 | .field 11 | = f.label :header_two 12 | %br 13 | = f.text_area :header_two 14 | .actions 15 | = f.submit 'Update', class: 'update-button' 16 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_technologies.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Display Technical Skills 3 | .settings-form-container#technolgies-display 4 | %p Chose how you would like to display your proficiency in tehnical skills - by years of experience, scale of 1 to 10, both, or none. 5 | = form_for [current_user, @portfolio] do |f| 6 | .form-technologies-display 7 | .field 8 | = f.label :show_years_exp 9 | = f.select :show_years_exp, [['Yes', true], ['No', false]], selected: @portfolio.show_years_exp 10 | .field 11 | = f.label :show_on_scale 12 | = f.select :show_proficiency, [['Yes', true], ['No', false]], selected: @portfolio.show_proficiency 13 | .actions 14 | = submit_tag 'Update', class: 'update-button' 15 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_theme.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Change Portfolio Theme 3 | .settings-form-container#change-portfolio-theme 4 | %p Pick a theme for your portfolio. More themes coming soon! 5 | %small Your current theme is 6 | %h5 7 | = @portfolio.theme 8 | = form_for [current_user, @portfolio] do |f| 9 | .form-portfolio-theme 10 | .field 11 | = f.label :theme 12 | = f.select :theme, @themes.map { |theme| [ theme, theme]}, selected: @portfolio.theme 13 | .actions 14 | = submit_tag 'Update', class: 'update-button' 15 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_change_url.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Change Portfolio URL 3 | .settings-form-container#change-url 4 | %p 5 | Your current portfolio URL is 6 | %b 7 | = "mydevportal.io/#{current_user.portfolios.first.url}" 8 | = form_for [current_user, @portfolio] do |f| 9 | .form-portfolio-url 10 | .field 11 | = f.label :url, 'Portfolio URL' 12 | = f.text_field :url, class: 'input-portfolio-url' 13 | .actions 14 | = submit_tag 'Update', class: 'update-button' 15 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_current_avatar_image.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Avatar Image Preview 3 | .settings-form-container.preview-image 4 | - if @portfolio_header.avatar_image.full.url 5 | - if @portfolio.show_avatar_image 6 | %img{ src: "#{@portfolio_header.avatar_image.full.url}"} 7 | - else 8 | %h5 You have chosen not to display an Avatar image 9 | - else 10 | %h5 You have not uploaded an Avatar image yet 11 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_current_cover_image.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Cover Image Preview 3 | .settings-form-container.preview-image 4 | - if @portfolio_header.cover_image.full.url 5 | - if @portfolio.show_cover_image 6 | %img{ src: "#{@portfolio_header.cover_image.preview.url}"} 7 | - else 8 | %h5 You have chosen not to display an Cover image 9 | - else 10 | %h5 You have not uploaded a Cover image yet 11 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/_new.html.haml: -------------------------------------------------------------------------------- 1 | .config-container 2 | %h4 Create a New Portfolio 3 | .settings-form-container#new-portfolio 4 | %p 5 | Want a portfolio that showcases a slightly different set of skills? 6 | Create a new portfolio with its own URL, projects, skills, etc... 7 | = form_for [current_user, Portfolio.new] do |f| 8 | .form-new-portfolio 9 | .field 10 | = f.label :url, 'New Portfolio URL' 11 | = f.text_field :url, class: 'input-new-portfolio-url' 12 | .actions 13 | = submit_tag 'Create', class: 'update-button' 14 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/edit.html.haml: -------------------------------------------------------------------------------- 1 | .portfolio-config-container 2 | .heading 3 | %h1 Main Settings 4 | = render partial: 'dashboard/dashboard/select_active_portfolio' 5 | .portfolio-config-main 6 | = render partial: 'change_url' 7 | = render partial: 'change_theme' 8 | = render partial: 'change_colors' 9 | = render partial: 'change_font_colors' 10 | = render partial: 'change_technologies' 11 | = render partial: 'new' 12 | .heading 13 | %h1 Header Settings 14 | .portfolio-config-main 15 | = render partial: 'change_header_text' 16 | = render partial: 'change_header_font_colors' 17 | = render partial: 'change_display_image' 18 | = render partial: 'change_header_images' 19 | = render partial: 'current_avatar_image' 20 | = render partial: 'current_cover_image' 21 | -------------------------------------------------------------------------------- /app/views/dashboard/portfolios/preview.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: 'dashboard/dashboard/select_active_portfolio' 2 | .preview-container 3 | .preview 4 | = render partial: "front_end/portfolio/themes/#{@portfolio.theme}" 5 | -------------------------------------------------------------------------------- /app/views/dashboard/projects/_form.html.haml: -------------------------------------------------------------------------------- 1 | = form_for [@portfolio, @project] do |f| 2 | .form-project 3 | .field 4 | = f.label :title 5 | %br 6 | = f.text_field :title 7 | .field 8 | = f.label :link 9 | %br 10 | = f.text_field :link 11 | .field 12 | = f.label :role 13 | %br 14 | = f.text_field :role 15 | .field 16 | = f.label :image 17 | %br 18 | = f.file_field :image, class: 'form-project-image' 19 | - if @project.persisted? 20 | - if @project.image.url 21 | .field.project-preview 22 | %img{ src: "#{@project.image.url}" } 23 | - else 24 | .field.project-preview 25 | %h5 You have not uploaded an image for this project yet 26 | .field 27 | = f.label :description 28 | %br 29 | = f.text_area :description, class: 'form-project-description' 30 | .field.tech-used 31 | = f.label :tech 32 | %br 33 | = f.text_area :tech, class: 'form-project-tech' 34 | .display_order 35 | = f.label :display_order 36 | = f.text_field :order, class: 'display-order-input' 37 | .actions 38 | - if @project.persisted? 39 | = link_to 'Cancel', portfolio_projects_path(@portfolio), class: 'cancel-button' 40 | = link_to 'Delete', portfolio_project_path(@portfolio, @project), class: 'delete-button', method: :delete, data: { confirm: 'Are you sure that you would like to delete this Application?' } 41 | = f.submit "#{@project.persisted? ? 'Update' : 'Create'}", class: 'update-button' 42 | -------------------------------------------------------------------------------- /app/views/dashboard/projects/_project_sidebar.html.haml: -------------------------------------------------------------------------------- 1 | .project-side-bar-container 2 | .project-side-bar 3 | %h4 Select Project 4 | = link_to new_portfolio_project_path(@portfolio) do 5 | .project-link.add-project{ class: @project.persisted? ? '' : 'active-project' } 6 | .add-project-icon 7 | %strong Add Project 8 | - @projects.each do |project| 9 | = link_to edit_portfolio_project_path(@portfolio, project.id) do 10 | .project-link{ class: project == @project ? 'active-project' : '' } 11 | = project.title 12 | -------------------------------------------------------------------------------- /app/views/dashboard/projects/_show.html.haml: -------------------------------------------------------------------------------- 1 | .project-mini-display-container 2 | %p 3 | %b Title: 4 | %br 5 | = project.title 6 | %p 7 | - if project.image.thumb.url 8 | = image_tag project.image.thumb.url 9 | %p 10 | %b Descrption: 11 | = "#{project.description[0..95]} ..." 12 | %p 13 | %b Role: 14 | %br 15 | = project.role 16 | %p 17 | %b Tech: 18 | = project.tech 19 | %p 20 | = link_to project.link, project.link, class: 'project-mini-link' 21 | %p 22 | = link_to 'Edit', edit_portfolio_project_path(@portfolio, project.id), class: 'edit-button' 23 | = link_to 'Delete', portfolio_project_path(@portfolio.id, project.id), class: 'delete-button', method: :delete, data: { confirm: 'Are you sure that you would like to delete this project?' } 24 | -------------------------------------------------------------------------------- /app/views/dashboard/projects/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: 'dashboard/dashboard/select_active_portfolio' 2 | .project-main 3 | = render partial: 'project_sidebar' 4 | .form-container-project 5 | %h4 Edit Project 6 | .project-form-sub-container 7 | = render partial: 'form' 8 | -------------------------------------------------------------------------------- /app/views/dashboard/projects/new.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: 'dashboard/dashboard/select_active_portfolio' 2 | .project-main 3 | = render partial: 'project_sidebar' 4 | .form-container-project 5 | %h4 Add a New Project 6 | .project-form-sub-container 7 | = render partial: 'form' 8 | -------------------------------------------------------------------------------- /app/views/dashboard/technologies/_form.html.haml: -------------------------------------------------------------------------------- 1 | = form_for [@portfolio, @technology] do |f| 2 | .form-technology 3 | .field 4 | = f.label :technology 5 | %br 6 | = f.text_field :name 7 | .field.exp-input 8 | = f.label :years_of_experience 9 | = f.text_field :years_exp, value: "#{@technology.years_exp ? @technology.years_exp : 0}", class: 'years-exp-field' 10 | .field.exp-input 11 | = f.label :proficiency 12 | = f.select :proficiency, ((0..10).map { |i| [i, i] }), selected: @technology.proficiency ? @technology.proficiency : 10 13 | .actions 14 | - if @technology.persisted? 15 | = link_to 'Cancel', portfolio_technologies_path(@portfolio), class: 'cancel' 16 | = f.submit "#{@technology.persisted? ? 'Update' : 'Add New'}", class: 'update-button' 17 | -------------------------------------------------------------------------------- /app/views/dashboard/technologies/_show.html.haml: -------------------------------------------------------------------------------- 1 | .technologies-show-main-container 2 | %table.table.table-striped.table-dark 3 | %thead 4 | %tr.table-heading 5 | %th{ scope: 'col' } Options 6 | %th{ scope: 'col' } Technology 7 | %th{ scope: 'col' } Years Exp 8 | %th{ scope: 'col' } Proficiency 9 | %tbody 10 | - @technologies.each do |technology| 11 | %tr 12 | %th{ scope: 'row' } 13 | .table-item-options 14 | = link_to edit_portfolio_technology_path(@portfolio, technology.id) do 15 | .technology-edit-icon{ 'data-placement' => 'right', title: 'Edit Technology' } 16 | = link_to portfolio_technology_path(@portfolio.id, technology.id), method: :delete do 17 | .technology-delete-icon{ 'data-placement' => 'right', title: 'Remove Technology' } 18 | %td= technology.name 19 | %td= technology.years_exp 20 | %td 21 | .show-proficiency 22 | .progress 23 | .progress-bar.bg-warning{ role: 'progressbar', 24 | 'aria-valuemin' => '0', 'aria-valuemax' => '10', 25 | style: "width: #{technology.proficiency * 10}%" } 26 | -------------------------------------------------------------------------------- /app/views/dashboard/technologies/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: 'dashboard/dashboard/select_active_portfolio' 2 | .technologies-main 3 | .technologies-form-container 4 | %h4 Add Known Technologies/Skills 5 | .technolgies-form-sub-container 6 | = render partial: 'form' 7 | = render partial: 'show' 8 | -------------------------------------------------------------------------------- /app/views/dashboard/technologies/new.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: 'dashboard/dashboard/select_active_portfolio' 2 | .technologies-main 3 | .technologies-form-container 4 | %h4 Add Known Technologies/Skills 5 | .technolgies-form-sub-container 6 | .technologies-explained 7 | %p 8 | Here you can add known technologies to your profile. Each technology can 9 | qualified by 'Proficiency' and 'Years Exp'. 10 | %p 11 | %strong 'Years Exp' 12 | is the number of years that you have experience with a given 13 | technology. 14 | %p 15 | %strong 'Proficiency' 16 | is your skill level on a scale of 1 to 10 with a given technology 17 | = render partial: 'form' 18 | = render partial: 'show' 19 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/components/_default_footer.html.haml: -------------------------------------------------------------------------------- 1 | .footer{ style: "background-color: #{@portfolio.color_four}" } 2 | .footer-body{ style: "color: #{@portfolio.font_color_two}"} 3 | .location 4 | %h3 Location 5 | = @about.location 6 | .contact 7 | %h3 Around the Web 8 | = @about.email 9 | .links{ style: "fill: #{@portfolio.font_color_two}"} 10 | - if @about.github.length > 0 11 | .github 12 | = link_to @about.github do 13 | = image_tag 'github.svg', class: 'social-link' 14 | - if @about.linkedin.length > 0 15 | .linkedin 16 | = link_to @about.linkedin do 17 | = image_tag 'linkedin.svg', class: 'social-link' 18 | - if @about.facebook.length > 0 19 | .facebook 20 | = link_to @about.facebook do 21 | = image_tag 'facebook.svg', class: 'social-link' 22 | - if @about.twitter.length > 0 23 | .twitter 24 | = link_to @about.twitter do 25 | = image_tag 'twitter.svg', class: 'social-link' 26 | - if @about.website.length > 0 27 | .website 28 | = link_to @about.website do 29 | = image_tag 'website.svg', class: 'social-link' 30 | .about-mini 31 | %h3 32 | = "About #{@first_name}" 33 | = @about.about_me_brief 34 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/components/_default_header.html.haml: -------------------------------------------------------------------------------- 1 | .header{ style: "background-color: #{@portfolio.color_one}; background-image: #{@portfolio.show_cover_image ? "url(#{@portfolio_header.cover_image.url})" : nil}" } 2 | .header-avatar 3 | - if @portfolio.show_avatar_image 4 | %img.avatar-image{ src: "#{@portfolio_header.avatar_image.full.url}" } 5 | .header-name{ style: "color: #{@portfolio_header.header_one_color}" } 6 | = @portfolio_header.header_one 7 | .header-subheader{ style: "color: #{@portfolio_header.header_two_color}" } 8 | = @portfolio_header.header_two 9 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/components/_default_technologies.html.haml: -------------------------------------------------------------------------------- 1 | .skills-header{ style: "border-color: #{@portfolio.font_color_two}", class: "#{@show_technology}" } 2 | %h5 Technology 3 | %h5 4 | = @portfolio.show_years_exp ? 'Experience' : nil 5 | %h5 6 | = @portfolio.show_proficiency ? 'Proficiency' : nil 7 | - @technologies.each do |technology| 8 | .technology{ class: "#{@show_technology}" } 9 | .show-name{ style: "color: #{@portfolio.font_color_two}"} 10 | = technology.name 11 | .show-years-exp{ style: "color: #{@portfolio.font_color_two}"} 12 | - if @portfolio.show_years_exp 13 | = "#{pluralize(technology.years_exp, 'year')}" 14 | .show-proficiency 15 | - if @portfolio.show_proficiency 16 | .progress 17 | .progress-bar{ role: 'progressbar', 18 | 'aria-valuemin' => '0', 'aria-valuemax' => '10', 19 | style: "width: #{technology.proficiency * 10}%; background-color: #{@portfolio.color_four};" } 20 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/components/_portfolio_gallary.html.haml: -------------------------------------------------------------------------------- 1 | .portfolio-gallary-container 2 | - @projects.each_with_index do |project, index| 3 | %button.gallary-item{type: 'button', 'data-toggle' => 'modal', 'data-target' => "#project-#{index + 1}", style: "background-image: url(#{project.image.large.url})"} 4 | .modal.fade{ id: "project-#{index + 1}", tabindex: '-1', role: 'dialog', 'aria-labelledby' => "project-#{index + 1}-label", 'aria-hidden' => 'true' } 5 | .modal-dialog{ role: 'document' } 6 | .modal-content 7 | .modal-header 8 | %h5.modal-title{ id: "project-#{index + 1}-label" } 9 | = project.title 10 | %button.close{ type: 'button', 'data-dismiss' => 'modal', 'aria-label' => 'close'} 11 | %span{ 'aria-hidden' => true} 12 | × 13 | .modal-body 14 | %img.modal-project-image{ src: "#{project.image.url}" } 15 | .modal-project-role 16 | %p 17 | %strong Role: 18 | = project.role 19 | .modal-project-tech 20 | %p 21 | %strong Tech Used: 22 | = project.tech 23 | .modal-project-link 24 | %p 25 | %strong Link: 26 | = project.link 27 | .modal-project-description 28 | %p 29 | %strong Description: 30 | = project.description 31 | .modal-footer 32 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/components/_portfolio_slider.html.haml: -------------------------------------------------------------------------------- 1 | = stylesheet_link_tag 'component-slider', media: 'all', 'data-turbolinks-track' => true 2 | %section.section.slider 3 | - @projects.count.downto(0).each do |index| 4 | %input.slider__radio{ type: 'radio', name: 'slider', id: "slide-#{index + 1}", checked: true } 5 | .slider__holder 6 | - @projects.each_with_index do |project, index| 7 | %label.slider__item.card{ for: "slide-#{index + 1}", class: "slider__item--#{index + 1}", 8 | style: "background-color: #{@portfolio.color_three}; color: #{@portfolio.font_color_one}"} 9 | .project-title 10 | = project.title 11 | .project-description 12 | = "#{project.description[0..400]}..." 13 | %img.project-image{ src: "#{project.image.small.url}" } 14 | .project-tech 15 | %h6 Tech Used 16 | = project.tech 17 | %button.image-button{type: 'button', 'data-toggle' => 'modal', 'data-target' => "#project-#{index + 1}", style: "background-image: url(#{project.image.large.url})"} 18 | %button.btn.show-more{ type: 'button', 'data-toggle' => 'modal', 'data-target' => "#project-#{index + 1}", style: "background-color: #{@portfolio.color_one}" } 19 | show more 20 | .modal.fade{ id: "project-#{index + 1}", tabindex: '-1', role: 'dialog', 'aria-labelledby' => "project-#{index + 1}-label", 'aria-hidden' => 'true' } 21 | .modal-dialog{ role: 'document' } 22 | .modal-content 23 | .modal-header 24 | %h5.modal-title{ id: "project-#{index + 1}-label" } 25 | = project.title 26 | %button.close{ type: 'button', 'data-dismiss' => 'modal', 'aria-label' => 'close'} 27 | %span{ 'aria-hidden' => true} 28 | × 29 | .modal-body 30 | %img.modal-project-image{ src: "#{project.image.url}" } 31 | .modal-project-role 32 | %p 33 | %strong Role: 34 | = project.role 35 | .modal-project-tech 36 | %p 37 | %strong Tech Used: 38 | = project.tech 39 | .modal-project-link 40 | %p 41 | %strong Link: 42 | = project.link 43 | .modal-project-description 44 | %p 45 | %strong Description: 46 | = project.description 47 | .modal-footer 48 | .bullets 49 | - @projects.count.times do |index| 50 | %label.bullets__item{ for: "slide-#{index + 1}", class: "bullets__item--#{index + 1}" } 51 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/show.html.haml: -------------------------------------------------------------------------------- 1 | = render partial: "front_end/portfolio/themes/#{@portfolio.theme}" 2 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/themes/_default.html.haml: -------------------------------------------------------------------------------- 1 | .default{ style: "color: #{@portfolio.font_color_one}"} 2 | .theme-container 3 | = render partial: 'front_end/portfolio/components/default_header' 4 | .portfolio{ style: "background-color: #{@portfolio.color_two}" } 5 | %h2 Portfolio 6 | = render partial: 'front_end/portfolio/components/portfolio_slider' 7 | .technical-skill{ style: "background-color: #{@portfolio.color_one}" } 8 | %h2 Technical Skills 9 | = render partial: 'front_end/portfolio/components/default_technologies' 10 | .about-me{ style: "background-color: #{@portfolio.color_two}" } 11 | %h2 About Me 12 | %p.about{ style: "color: #{@portfolio.font_color_two}"} 13 | = @about.about_me 14 | = render partial: 'front_end/portfolio/components/default_footer' 15 | -------------------------------------------------------------------------------- /app/views/front_end/portfolio/themes/_default_gallary.html.haml: -------------------------------------------------------------------------------- 1 | .default{ style: "color: #{@portfolio.font_color_one}"} 2 | .theme-container 3 | = render partial: 'front_end/portfolio/components/default_header' 4 | .portfolio{ style: "background-color: #{@portfolio.color_two}" } 5 | %h2 Portfolio 6 | = render partial: 'front_end/portfolio/components/portfolio_gallary' 7 | .technical-skill{ style: "background-color: #{@portfolio.color_one}" } 8 | %h2 Technical Skills 9 | = render partial: 'front_end/portfolio/components/default_technologies' 10 | .about-me{ style: "background-color: #{@portfolio.color_two}" } 11 | %h2 About Me 12 | %p.about{ style: "color: #{@portfolio.font_color_two}"} 13 | = @about.about_me 14 | = render partial: 'front_end/portfolio/components/default_footer' 15 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %title MyDevPortal 5 | = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true 6 | = javascript_include_tag 'application', 'data-turbolinks-track' => true 7 | = csrf_meta_tags 8 | %link{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' } 9 | 10 | %body 11 | - if flash[:alert] 12 | .alert.alert-warning.alert-dismissible.fade.show{ role: 'alert' } 13 | = alert 14 | %button.close{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'close' } 15 | %span{ 'aria-hidden' => 'true' } 16 | × 17 | = yield 18 | -------------------------------------------------------------------------------- /app/views/layouts/front_end/portfolio.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %title 5 | = @portfolio.url 6 | = stylesheet_link_tag 'application-themes', media: 'all', 'data-turbolinks-track' => true 7 | = javascript_include_tag 'application', 'data-turbolinks-track' => true 8 | = javascript_include_tag 'portfolio', 'data-turbolinks-track' => true 9 | = csrf_meta_tags 10 | %link{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' } 11 | %body 12 | - if flash[:alert] 13 | .alert.alert-warning.alert-dismissible.fade.show{ role: 'alert' } 14 | = alert 15 | %button.close{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'close' } 16 | %span{ 'aria-hidden' => 'true' } 17 | × 18 | 19 | = yield 20 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /app/views/users/confirmations/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Resend confirmation instructions

3 | 4 | <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> 5 | <%= devise_error_messages! %> 6 | 7 |
8 | <%= f.label :email %>
9 | <%= f.email_field :email, autofocus: true, value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> 10 |
11 | 12 |
13 | <%= f.submit "Resend confirmation instructions" %> 14 |
15 | <% end %> 16 | 17 | <%= render "devise/shared/links" %> 18 |
19 | -------------------------------------------------------------------------------- /app/views/users/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Welcome <%= @email %>!

3 | 4 |

You can confirm your account email through the link below:

5 | 6 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

7 |
8 | -------------------------------------------------------------------------------- /app/views/users/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /app/views/users/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

We're contacting you to notify you that your password has been changed.

4 | -------------------------------------------------------------------------------- /app/views/users/mailer/reset_password_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Someone has requested a link to change your password. You can do this through the link below.

4 | 5 |

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

6 | 7 |

If you didn't request this, please ignore this email.

8 |

Your password won't change until you access the link above and create a new one.

9 | -------------------------------------------------------------------------------- /app/views/users/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /app/views/users/passwords/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Change your password

3 | 4 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> 5 | <%= devise_error_messages! %> 6 | <%= f.hidden_field :reset_password_token %> 7 | 8 |
9 | <%= f.label :password, "New password" %>
10 | <% if @minimum_password_length %> 11 | (<%= @minimum_password_length %> characters minimum)
12 | <% end %> 13 | <%= f.password_field :password, autofocus: true, autocomplete: "off" %> 14 |
15 | 16 |
17 | <%= f.label :password_confirmation, "Confirm new password" %>
18 | <%= f.password_field :password_confirmation, autocomplete: "off" %> 19 |
20 | 21 |
22 | <%= f.submit "Change my password" %> 23 |
24 | <% end %> 25 | 26 | <%= render "devise/shared/links" %> 27 |
28 | -------------------------------------------------------------------------------- /app/views/users/passwords/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Forgot your password?

3 | 4 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> 5 | <%= devise_error_messages! %> 6 | 7 |
8 | <%= f.label :email %>
9 | <%= f.email_field :email, autofocus: true %> 10 |
11 | 12 |
13 | <%= f.submit "Send me reset password instructions" %> 14 |
15 | <% end %> 16 | 17 | <%= render "devise/shared/links" %> 18 |
19 | -------------------------------------------------------------------------------- /app/views/users/registrations/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Change Password/Email

3 |
4 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> 5 | <%= devise_error_messages! %> 6 | 7 |
8 | <%= f.label :new_email %>
9 | <%= f.email_field :email, autofocus: true %> 10 |
11 | (enter a new email here if you would like to change your email address) 12 |
13 | 14 | <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> 15 |
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
16 | <% end %> 17 | 18 |
19 | <%= f.label :new_password %>
20 | <%= f.password_field :password, autocomplete: "off" %> 21 |
22 | (leave blank if you don't want to change it) 23 | <% if @minimum_password_length %> 24 | <% end %> 25 |
26 | 27 |
28 | <%= f.label :new_password_confirmation %>
29 | <%= f.password_field :password_confirmation, autocomplete: "off" %> 30 |
31 | 32 |
33 | <%= f.label :current_password %>
34 | <%= f.password_field :current_password, autocomplete: "off" %> 35 |
36 | (we need your current password to confirm your changes) 37 |
38 | 39 |
40 | <%= f.submit "Update" %> 41 |
42 | <% end %> 43 | 52 | <%= link_to "Back", :back %> 53 |
54 |
55 | -------------------------------------------------------------------------------- /app/views/users/registrations/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Sign up

3 | 4 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> 5 | <%= devise_error_messages! %> 6 | 7 |
8 | <%= f.label :email %>
9 | <%= f.email_field :email, autofocus: true %> 10 |
11 | 12 |
13 | <%= f.label :password %> 14 | <% if @minimum_password_length %> 15 | (<%= @minimum_password_length %> characters minimum) 16 | <% end %>
17 | <%= f.password_field :password, autocomplete: "off" %> 18 |
19 | 20 |
21 | <%= f.label :password_confirmation %>
22 | <%= f.password_field :password_confirmation, autocomplete: "off" %> 23 |
24 | 25 |
26 | <%= f.submit "Sign up" %> 27 |
28 | <% end %> 29 | 30 | <%= render "devise/shared/links" %> 31 |
32 | -------------------------------------------------------------------------------- /app/views/users/sessions/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Log in

3 | 4 | <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> 5 |
6 | <%= f.label :email %>
7 | <%= f.email_field :email, autofocus: true %> 8 |
9 | 10 |
11 | <%= f.label :password %>
12 | <%= f.password_field :password, autocomplete: "off" %> 13 |
14 | 15 | <% if devise_mapping.rememberable? -%> 16 |
17 | <%= f.label :remember_me %> 18 | <%= f.check_box :remember_me %> 19 |
20 | <% end -%> 21 | 22 |
23 | <%= f.submit "Log in" %> 24 |
25 | <% end %> 26 | 27 | <%= render "devise/shared/links" %> 28 |
29 | -------------------------------------------------------------------------------- /app/views/users/shared/_links.html.erb: -------------------------------------------------------------------------------- 1 | <%- if controller_name != 'sessions' %> 2 | <%= link_to "Log in", new_session_path(resource_name) %>
3 | <% end -%> 4 | 5 | <%- if devise_mapping.registerable? && controller_name != 'registrations' %> 6 | <%= link_to "Sign up", new_registration_path(resource_name) %>
7 | <% end -%> 8 | 9 | <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> 10 | <%= link_to "Forgot your password?", new_password_path(resource_name) %>
11 | <% end -%> 12 | 13 | <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> 14 | <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
15 | <% end -%> 16 | 17 | <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> 18 | <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
19 | <% end -%> 20 | 21 | <%- if devise_mapping.omniauthable? %> 22 | <%- resource_class.omniauth_providers.each do |provider| %> 23 | <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %>
24 | <% end -%> 25 | <% end -%> 26 | -------------------------------------------------------------------------------- /app/views/users/unlocks/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Resend unlock instructions

3 | 4 | <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> 5 | <%= devise_error_messages! %> 6 | 7 |
8 | <%= f.label :email %>
9 | <%= f.email_field :email, autofocus: true %> 10 |
11 | 12 |
13 | <%= f.submit "Resend unlock instructions" %> 14 |
15 | <% end %> 16 | 17 | <%= render "devise/shared/links" %> 18 |
19 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a starting point to setup your application. 15 | # Add necessary setup steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | # Install JavaScript dependencies if using Yarn 22 | # system('bin/yarn') 23 | 24 | 25 | # puts "\n== Copying sample files ==" 26 | # unless File.exist?('config/database.yml') 27 | # cp 'config/database.yml.sample', 'config/database.yml' 28 | # end 29 | 30 | puts "\n== Preparing database ==" 31 | system! 'bin/rails db:setup' 32 | 33 | puts "\n== Removing old logs and tempfiles ==" 34 | system! 'bin/rails log:clear tmp:clear' 35 | 36 | puts "\n== Restarting application server ==" 37 | system! 'bin/rails restart' 38 | end 39 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require 'rubygems' 8 | require 'bundler' 9 | 10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) 11 | spring = lockfile.specs.detect { |spec| spec.name == "spring" } 12 | if spring 13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path 14 | gem 'spring', spring.version 15 | require 'spring/binstub' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a way to update your development environment automatically. 15 | # Add necessary update steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | puts "\n== Updating database ==" 22 | system! 'bin/rails db:migrate' 23 | 24 | puts "\n== Removing old logs and tempfiles ==" 25 | system! 'bin/rails log:clear tmp:clear' 26 | 27 | puts "\n== Restarting application server ==" 28 | system! 'bin/rails restart' 29 | end 30 | -------------------------------------------------------------------------------- /bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | VENDOR_PATH = File.expand_path('..', __dir__) 3 | Dir.chdir(VENDOR_PATH) do 4 | begin 5 | exec "yarnpkg #{ARGV.join(" ")}" 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /config/application.example.yml: -------------------------------------------------------------------------------- 1 | MAILGUN_API_KEY: YOUR KEY 2 | MAILGUN_DOMAIN: YOUR DOMAIN 3 | S3_KEY: YOUR KEY 4 | S3_SECRET: YOUR SECRET 5 | S3_REGION: YOUR REGION 6 | S3_BUCKET: YOUR BUCKET 7 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module MyDevPortalDashboard 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 5.1 13 | 14 | # Settings in config/environments/* take precedence over those specified here. 15 | # Application configuration should go into files in config/initializers 16 | # -- all .rb files in that directory are automatically loaded. 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: async 6 | 7 | production: 8 | adapter: redis 9 | url: redis://localhost:6379/1 10 | channel_prefix: my_dev_portal_dashboard_production 11 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: postgresql 9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 10 | timeout: 5000 11 | 12 | 13 | development: 14 | <<: *default 15 | database: my_dev_portal_development 16 | 17 | # Warning: The database defined as "test" will be erased and 18 | # re-generated from your development database when you run "rake". 19 | # Do not set this db to the same as development or production. 20 | test: 21 | <<: *default 22 | database: my_dev_portal_test 23 | 24 | production: 25 | <<: *default 26 | database: my_dev_portal_production 27 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports. 13 | config.consider_all_requests_local = true 14 | 15 | # Enable/disable caching. By default caching is disabled. 16 | if Rails.root.join('tmp/caching-dev.txt').exist? 17 | config.action_controller.perform_caching = true 18 | 19 | config.cache_store = :memory_store 20 | config.public_file_server.headers = { 21 | 'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}" 22 | } 23 | else 24 | config.action_controller.perform_caching = false 25 | 26 | config.cache_store = :null_store 27 | end 28 | 29 | config.action_mailer.perform_deliveries = true 30 | config.action_mailer.raise_delivery_errors = true 31 | config.action_mailer.default :charset => "utf-8" 32 | config.action_mailer.default_url_options = { host: 'localhost:3000' } 33 | config.action_mailer.delivery_method = :smtp 34 | config.action_mailer.mailgun_settings = { 35 | api_key: ENV['MAILGUN_API_KEY'], 36 | domain: ENV['MAILGUN_DOMAIN'] 37 | } 38 | 39 | # Don't care if the mailer can't send. 40 | config.action_mailer.raise_delivery_errors = false 41 | 42 | config.action_mailer.perform_caching = false 43 | 44 | # Print deprecation notices to the Rails logger. 45 | config.active_support.deprecation = :log 46 | 47 | # Raise an error on page load if there are pending migrations. 48 | config.active_record.migration_error = :page_load 49 | 50 | # Debug mode disables concatenation and preprocessing of assets. 51 | # This option may cause significant delays in view rendering with a large 52 | # number of complex assets. 53 | config.assets.debug = true 54 | 55 | # Suppress logger output for asset requests. 56 | config.assets.quiet = true 57 | 58 | # Raises error for missing translations 59 | # config.action_view.raise_on_missing_translations = true 60 | 61 | # Use an evented file watcher to asynchronously detect changes in source code, 62 | # routes, locales, etc. This feature depends on the listen gem. 63 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 64 | end 65 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure public file server for tests with Cache-Control for performance. 16 | config.public_file_server.enabled = true 17 | config.public_file_server.headers = { 18 | 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}" 19 | } 20 | 21 | # Show full error reports and disable caching. 22 | config.consider_all_requests_local = true 23 | config.action_controller.perform_caching = false 24 | 25 | # Raise exceptions instead of rendering exception templates. 26 | config.action_dispatch.show_exceptions = false 27 | 28 | # Disable request forgery protection in test environment. 29 | config.action_controller.allow_forgery_protection = false 30 | config.action_mailer.perform_caching = false 31 | 32 | # Tell Action Mailer not to deliver emails to the real world. 33 | # The :test delivery method accumulates sent emails in the 34 | # ActionMailer::Base.deliveries array. 35 | config.action_mailer.delivery_method = :test 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | # Add Yarn node_modules folder to the asset load path. 9 | Rails.application.config.assets.paths << Rails.root.join('node_modules') 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in the app/assets 13 | # folder are already added. 14 | Rails.application.config.assets.precompile += %w[application-dashboard.css 15 | application-themes.css 16 | component-slider.css 17 | dashboard.js 18 | portfolio.js 19 | filterrific/filterrific-spinner.gif] 20 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/carrier_wave.rb: -------------------------------------------------------------------------------- 1 | require 'carrierwave/orm/activerecord' 2 | # put this in config/initializers/carrierwave.rb 3 | module CarrierWave 4 | module MiniMagick 5 | def quality(percentage) 6 | manipulate! do |img| 7 | img.quality(percentage.to_s) 8 | img = yield(img) if block_given? 9 | img 10 | end 11 | end 12 | end 13 | end 14 | 15 | CarrierWave.configure do |config| 16 | config.fog_provider = 'fog/aws' 17 | config.fog_credentials = { 18 | provider: 'AWS', 19 | aws_access_key_id: ENV['S3_KEY'], 20 | aws_secret_access_key: ENV['S3_SECRET'], 21 | region: ENV['S3_REGION'], 22 | } 23 | config.fog_directory = ENV['S3_BUCKET'] 24 | end 25 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/themes.rb: -------------------------------------------------------------------------------- 1 | # Creats an array of themes from the app/views/portfolios/themes 2 | class Themes 3 | def self.array 4 | @array ||= Dir['app/views/front_end/portfolio/themes/*'] 5 | .map { |file| file.rpartition('/').last.partition('.').first[1..-1] } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. If you use this option 30 | # you need to make sure to reconnect any threads in the `on_worker_boot` 31 | # block. 32 | # 33 | # preload_app! 34 | 35 | # If you are preloading your application and using Active Record, it's 36 | # recommended that you close any connections to the database before workers 37 | # are forked to prevent connection leakage. 38 | # 39 | # before_fork do 40 | # ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) 41 | # end 42 | 43 | # The code in the `on_worker_boot` will be called if you are using 44 | # clustered mode by specifying a number of `workers`. After each worker 45 | # process is booted, this block will be run. If you are using the `preload_app!` 46 | # option, you will want to use this block to reconnect to any threads 47 | # or connections that may have been created at application boot, as Ruby 48 | # cannot share connections between processes. 49 | # 50 | # on_worker_boot do 51 | # ActiveRecord::Base.establish_connection if defined?(ActiveRecord) 52 | # end 53 | # 54 | 55 | # Allow puma to be restarted by `rails restart` command. 56 | plugin :tmp_restart 57 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root 'home#index' 3 | patch 'select_active_portfolio' => 'dashboard/users#update' 4 | get ':portfolio' => 'front_end/portfolio#show' 5 | get 'preview/:portfolio' => 'front_end/portfolio#preview' 6 | 7 | scope module: 'dashboard' do 8 | resources :portfolios, only: %i[] do 9 | resources :projects 10 | resources :technologies 11 | resources :portfolio_headers, only: %i[create update edit] 12 | resources :abouts 13 | end 14 | resources :users, only: %i[update] do 15 | resources :job_applications 16 | resources :portfolios, only: %i[create update destroy edit new] 17 | resources :dashboard, only: %i[index] 18 | resources :blogs, only: %i[show] 19 | end 20 | end 21 | 22 | devise_for :users, controllers: { sessions: 'users/sessions', 23 | registrations: 'users/registrations', 24 | passwords: 'users/passwords' } 25 | end 26 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | # Shared secrets are available across all environments. 14 | 15 | # shared: 16 | # api_key: a1B2c3D4e5F6 17 | 18 | # Environmental secrets are only available for that specific environment. 19 | 20 | development: 21 | secret_key_base: 717a49eeb45ea23e8c045270aba101550dab360be8a1d9903d4f1e68ca69c8188a712daf7788571a47666006d71a61dab1948de6c7d9969073e3a4533fc41b7e 22 | 23 | test: 24 | secret_key_base: 361f9c6119bb20bc94a3c5679e383c6b7376ea9f714f167574dc2ecd07b5408cd6b27f1e69017fcccafefe360df30335ac2f1c4a60a37ed5412086c357a6ee62 25 | 26 | # Do not keep production secrets in the unencrypted secrets file. 27 | # Instead, either read values from the environment. 28 | # Or, use `bin/rails secrets:setup` to configure encrypted secrets 29 | # and move the `production:` environment over there. 30 | 31 | production: 32 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 33 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | %w( 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ).each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /db/migrate/20171204231450_devise_create_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateUsers < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :users do |t| 4 | ## Database authenticatable 5 | t.string :email, null: false, default: "" 6 | t.string :encrypted_password, null: false, default: "" 7 | 8 | ## Recoverable 9 | t.string :reset_password_token 10 | t.datetime :reset_password_sent_at 11 | 12 | ## Rememberable 13 | t.datetime :remember_created_at 14 | 15 | ## Trackable 16 | t.integer :sign_in_count, default: 0, null: false 17 | t.datetime :current_sign_in_at 18 | t.datetime :last_sign_in_at 19 | t.string :current_sign_in_ip 20 | t.string :last_sign_in_ip 21 | 22 | ## Confirmable 23 | # t.string :confirmation_token 24 | # t.datetime :confirmed_at 25 | # t.datetime :confirmation_sent_at 26 | # t.string :unconfirmed_email # Only if using reconfirmable 27 | 28 | ## Lockable 29 | # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts 30 | # t.string :unlock_token # Only if unlock strategy is :email or :both 31 | # t.datetime :locked_at 32 | 33 | 34 | t.timestamps null: false 35 | end 36 | 37 | add_index :users, :email, unique: true 38 | add_index :users, :reset_password_token, unique: true 39 | # add_index :users, :confirmation_token, unique: true 40 | # add_index :users, :unlock_token, unique: true 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /db/migrate/20171205193732_create_portfolios.rb: -------------------------------------------------------------------------------- 1 | class CreatePortfolios < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :portfolios do |t| 4 | t.references :user, foreign_key: true 5 | t.string :url 6 | t.string :theme 7 | t.string :color_one 8 | t.string :color_two 9 | t.string :color_three 10 | t.string :color_four 11 | t.string :font_color_one 12 | t.string :font_color_two 13 | t.boolean :show_cover_image 14 | t.boolean :show_avatar_image 15 | t.boolean :show_years_exp 16 | t.boolean :show_proficiency 17 | 18 | t.timestamps 19 | end 20 | add_index :portfolios, :url, unique: true 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /db/migrate/20171207235120_create_projects.rb: -------------------------------------------------------------------------------- 1 | class CreateProjects < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :projects do |t| 4 | t.references :portfolio, foreign_key: true 5 | t.string :title 6 | t.string :link 7 | t.text :description 8 | t.string :image 9 | t.text :tech 10 | t.string :role 11 | t.integer :order 12 | 13 | t.timestamps 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /db/migrate/20171210212628_create_technologies.rb: -------------------------------------------------------------------------------- 1 | class CreateTechnologies < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :technologies do |t| 4 | t.string :name, limit: 20 5 | t.references :portfolio, foreign_key: true 6 | t.integer :years_exp 7 | t.integer :proficiency 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20171211213207_create_portfolio_headers.rb: -------------------------------------------------------------------------------- 1 | class CreatePortfolioHeaders < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :portfolio_headers do |t| 4 | t.belongs_to :portfolio, index: true 5 | t.string :header_one 6 | t.string :header_one_color 7 | t.string :header_two 8 | t.string :header_two_color 9 | t.string :cover_image 10 | t.string :avatar_image 11 | 12 | t.timestamps 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20171212225416_create_abouts.rb: -------------------------------------------------------------------------------- 1 | class CreateAbouts < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :abouts do |t| 4 | t.references :portfolio, foreign_key: true 5 | t.text :about_me 6 | t.string :location 7 | t.string :about_me_brief 8 | t.string :email 9 | t.string :github 10 | t.string :linkedin 11 | t.string :twitter 12 | t.string :facebook 13 | t.string :website 14 | 15 | t.timestamps 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /db/migrate/20171219205323_change_column_name.rb: -------------------------------------------------------------------------------- 1 | class ChangeColumnName < ActiveRecord::Migration[5.1] 2 | def change 3 | rename_column :projects, :descrption, :description 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20171226173830_create_job_applications.rb: -------------------------------------------------------------------------------- 1 | class CreateJobApplications < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :job_applications do |t| 4 | t.references :user, foreign_key: true 5 | t.date :first_contact_date 6 | t.string :company_name 7 | t.string :company_website 8 | t.string :job_location 9 | t.string :enthusiasm 10 | t.string :job_title 11 | t.string :job_link 12 | t.string :referral 13 | t.string :referral_type 14 | t.string :status 15 | t.string :industry 16 | t.text :notes 17 | 18 | t.timestamps 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /db/migrate/20171231161435_add_options_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddOptionsToUsers < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :users, :options, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) 7 | # Character.create(name: 'Luke', movie: movies.first) 8 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/lib/assets/.keep -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/lib/tasks/.keep -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/log/.keep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my_dev_portal_dashboard", 3 | "private": true, 4 | "dependencies": {} 5 | } 6 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

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

63 |
64 |

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

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

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

63 |
64 |

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

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

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

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /public/uploads/project/image/1/large_test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/project/image/1/large_test.jpg -------------------------------------------------------------------------------- /public/uploads/project/image/1/medium_test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/project/image/1/medium_test.jpg -------------------------------------------------------------------------------- /public/uploads/project/image/1/small_test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/project/image/1/small_test.jpg -------------------------------------------------------------------------------- /public/uploads/project/image/1/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/project/image/1/test.jpg -------------------------------------------------------------------------------- /public/uploads/project/image/1/thumb_test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/project/image/1/thumb_test.jpg -------------------------------------------------------------------------------- /public/uploads/tmp/1512691563-15357-0002-7928/IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512691563-15357-0002-7928/IMG_0736.JPG -------------------------------------------------------------------------------- /public/uploads/tmp/1512691563-15357-0002-7928/thumb_IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512691563-15357-0002-7928/thumb_IMG_0736.JPG -------------------------------------------------------------------------------- /public/uploads/tmp/1512691666-15357-0003-7880/IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512691666-15357-0003-7880/IMG_0736.JPG -------------------------------------------------------------------------------- /public/uploads/tmp/1512691666-15357-0003-7880/thumb_IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512691666-15357-0003-7880/thumb_IMG_0736.JPG -------------------------------------------------------------------------------- /public/uploads/tmp/1512692438-16702-0001-5998/IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512692438-16702-0001-5998/IMG_0736.JPG -------------------------------------------------------------------------------- /public/uploads/tmp/1512692438-16702-0001-5998/thumb_IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512692438-16702-0001-5998/thumb_IMG_0736.JPG -------------------------------------------------------------------------------- /public/uploads/tmp/1512692498-16702-0002-9124/IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512692498-16702-0002-9124/IMG_0736.JPG -------------------------------------------------------------------------------- /public/uploads/tmp/1512692498-16702-0002-9124/thumb_IMG_0736.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/public/uploads/tmp/1512692498-16702-0002-9124/thumb_IMG_0736.JPG -------------------------------------------------------------------------------- /spec/controllers/dashboard/abouts_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Dashboard::AboutsController, type: :controller do 4 | login_user 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: subject.current_user) } 6 | 7 | let(:attributes) do 8 | { about_me: 'testing title', 9 | about_me_brief: 'exiting stuff', 10 | location: 'here', 11 | github: '', 12 | linkedin: '', 13 | facebook: '', 14 | twitter: '', 15 | website: '' } 16 | end 17 | 18 | describe 'about#create' do 19 | it 'Allows user to create a new project' do 20 | post :create, params: { portfolio_id: portfolio.id, 21 | about: attributes } 22 | record = About.new 23 | record.portfolio_id = portfolio.id 24 | record.valid? 25 | 26 | expect(About.all.count).to eq(1) 27 | end 28 | it 'Redirects to about view' do 29 | post :create, params: { portfolio_id: portfolio.id, 30 | about: attributes } 31 | expect(response).to redirect_to(portfolio_abouts_path(portfolio)) 32 | end 33 | end 34 | 35 | describe 'about#update' do 36 | it 'Allows use to update project' do 37 | post :create, params: { portfolio_id: portfolio.id, 38 | about: attributes } 39 | patch :update, params: { portfolio_id: portfolio.id, 40 | id: About.first.id, 41 | about: { about_me: 'working' } } 42 | expect(About.first.about_me).to eq('working') 43 | end 44 | it 'Redirects to about view' do 45 | post :create, params: { portfolio_id: portfolio.id, 46 | about: attributes } 47 | patch :update, params: { portfolio_id: portfolio.id, 48 | id: About.first.id, 49 | about: { about_me: 'working' } } 50 | expect(response).to redirect_to(portfolio_abouts_path(portfolio)) 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /spec/controllers/dashboard/dashboard_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Dashboard::DashboardController, type: :controller do 4 | 5 | end 6 | -------------------------------------------------------------------------------- /spec/controllers/dashboard/portfolio_headers_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Dashboard::PortfolioHeadersController, type: :controller do 4 | login_user 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: subject.current_user) } 6 | 7 | let(:attributes) do 8 | { header_one: 'testing title', 9 | header_two: 'exiting stuff', 10 | header_two_color: '#ffffff', 11 | header_one_color: '#ffffff' } 12 | end 13 | 14 | describe 'portfolio_header#create' do 15 | it 'Allows user to create a new project' do 16 | post :create, params: { portfolio_id: portfolio.id, 17 | portfolio_header: attributes } 18 | expect(PortfolioHeader.all.count).to eq(1) 19 | end 20 | it 'Redirects to portfolio_header view' do 21 | post :create, params: { portfolio_id: portfolio.id, 22 | portfolio_header: attributes } 23 | expect(response).to redirect_to(edit_user_portfolio_path(subject.current_user, portfolio)) 24 | end 25 | end 26 | 27 | describe 'portfolio_header#update' do 28 | it 'Allows use to update project' do 29 | post :create, params: { portfolio_id: portfolio.id, 30 | portfolio_header: attributes } 31 | patch :update, params: { portfolio_id: portfolio.id, 32 | id: PortfolioHeader.first.id, 33 | portfolio_header: { header_one: 'working' } } 34 | expect(PortfolioHeader.first.header_one).to eq('working') 35 | end 36 | it 'Redirects to project view' do 37 | post :create, params: { portfolio_id: portfolio.id, 38 | portfolio_header: attributes } 39 | patch :update, params: { portfolio_id: portfolio.id, 40 | id: PortfolioHeader.first.id, 41 | portfolio_header: { header_one: 'working' } } 42 | expect(response).to redirect_to(edit_user_portfolio_path(subject.current_user, portfolio)) 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/controllers/dashboard/portfolios_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Dashboard::PortfoliosController, type: :controller do 4 | login_user 5 | let(:attributes) do 6 | { url: 'testing', 7 | color_one: '#ffffff', 8 | color_two: '#ffffff', 9 | color_three: '#ffffff', 10 | color_four: '#ffffff', 11 | font_color_one: '#ffffff', 12 | font_color_two: '#ffffff', 13 | theme: 'default', 14 | id: 1 } 15 | end 16 | let(:attributes2) do 17 | { url: 'test', 18 | color_one: '#ffffff', 19 | color_two: '#ffffff', 20 | color_three: '#ffffff', 21 | color_four: '#ffffff', 22 | font_color_one: '#ffffff', 23 | font_color_two: '#ffffff', 24 | theme: 'default', 25 | id: 1 } 26 | end 27 | 28 | describe 'portfolio#create' do 29 | it 'Lets new user create a portfolio' do 30 | subject.current_user.portfolios.create(attributes2) 31 | post :create, params: {user_id: subject.current_user.id, portfolio: attributes } 32 | expect(subject.current_user.portfolios[0].url).to eq('testing') 33 | end 34 | it 'Redirects to dashboard#index' do 35 | subject.current_user.portfolios.create(attributes2) 36 | post :create, params: {user_id: subject.current_user.id, portfolio: attributes } 37 | expect(response).to redirect_to(user_dashboard_index_path(subject.current_user)) 38 | end 39 | end 40 | 41 | describe 'portfolio#update' do 42 | let(:portfolio) { subject.current_user.portfolios.create(attributes) } 43 | it 'Lets user edit portfolio URL' do 44 | patch :update, params: { user_id: subject.current_user.id, 45 | id: portfolio.id, 46 | portfolio: { url: 'test' }, 47 | user: subject.current_user } 48 | expect(subject.current_user.portfolios.first.url).to eq('test') 49 | end 50 | it 'on success it reloads the same page' do 51 | patch :update, params: { user_id: subject.current_user.id, 52 | id: portfolio.id, 53 | portfolio: { url: 'test' }, 54 | user: subject.current_user } 55 | puts portfolio.errors.full_messages 56 | expect(response).to redirect_to(edit_user_portfolio_path(subject.current_user, portfolio)) 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /spec/controllers/dashboard/projects_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Dashboard::ProjectsController, type: :controller do 4 | login_user 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: subject.current_user) } 6 | 7 | let(:valid_attributes) do 8 | { title: 'testing title', 9 | description: 'exiting stuff', 10 | role: 'BMOC', 11 | tech: 'fancey things', 12 | link: 'a place', 13 | order: 1 } 14 | end 15 | 16 | describe 'projects#create' do 17 | it 'Allows user to create a new project' do 18 | post :create, params: { portfolio_id: portfolio.id, 19 | project: valid_attributes } 20 | expect(portfolio.projects.all.count).to eq(1) 21 | end 22 | it 'Redirects to project view' do 23 | post :create, params: { portfolio_id: portfolio.id, 24 | project: valid_attributes } 25 | expect(response).to redirect_to(portfolio_projects_path(portfolio)) 26 | end 27 | end 28 | 29 | describe 'projects#update' do 30 | it 'Allows use to update project' do 31 | post :create, params: { portfolio_id: portfolio.id, 32 | project: valid_attributes } 33 | patch :update, params: { portfolio_id: portfolio.id, 34 | id: portfolio.projects.first.id, 35 | project: { title: 'working' } } 36 | expect(portfolio.projects.first.title).to eq('working') 37 | end 38 | it 'Redirects to project view' do 39 | post :create, params: { portfolio_id: portfolio.id, 40 | project: valid_attributes } 41 | patch :update, params: { portfolio_id: portfolio.id, 42 | id: portfolio.projects.first.id, 43 | project: { title: 'working' } } 44 | expect(response).to redirect_to(portfolio_projects_path(portfolio)) 45 | end 46 | end 47 | 48 | describe 'projects#destroy' do 49 | it 'Allows user to delete project' do 50 | post :create, params: { portfolio_id: portfolio.id, 51 | project: valid_attributes } 52 | delete :destroy, params: { portfolio_id: portfolio.id, 53 | id: portfolio.projects.first.id } 54 | expect(portfolio.projects.all.count).to eq(0) 55 | end 56 | it 'Redirects to project view' do 57 | post :create, params: { portfolio_id: portfolio.id, 58 | project: valid_attributes } 59 | delete :destroy, params: { portfolio_id: portfolio.id, 60 | id: portfolio.projects.first.id } 61 | expect(response).to redirect_to(portfolio_projects_path(portfolio)) 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /spec/controllers/dashboard/technologies_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Dashboard::TechnologiesController, type: :controller do 4 | login_user 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: subject.current_user) } 6 | let(:valid_attributes) do 7 | { name: 'Ruby', 8 | years_exp: 1, 9 | proficiency: 8, 10 | show_years_exp: true, 11 | show_proficiency: true } 12 | end 13 | 14 | describe 'technologies#create' do 15 | it 'Allows user to create a new technology' do 16 | post :create, params: { portfolio_id: portfolio.id, 17 | technology: valid_attributes } 18 | expect(portfolio.technologies.all.count).to eq(1) 19 | end 20 | it 'Redirects to technologies view' do 21 | post :create, params: { portfolio_id: portfolio.id, 22 | technology: valid_attributes } 23 | expect(response).to redirect_to(portfolio_technologies_path(portfolio)) 24 | end 25 | end 26 | 27 | describe 'technologies#update' do 28 | it 'Allows use to update project' do 29 | post :create, params: { portfolio_id: portfolio.id, 30 | technology: valid_attributes } 31 | patch :update, params: { portfolio_id: portfolio.id, 32 | id: portfolio.technologies.first.id, 33 | technology: { name: 'Ruby on Rails' } } 34 | expect(portfolio.technologies.first.name).to eq('Ruby on Rails') 35 | end 36 | it 'Redirects to technologies view' do 37 | post :create, params: { portfolio_id: portfolio.id, 38 | technology: valid_attributes } 39 | patch :update, params: { portfolio_id: portfolio.id, 40 | id: portfolio.technologies.first.id, 41 | technology: { name: 'Ruby on Rails' } } 42 | expect(response).to redirect_to(portfolio_technologies_path(portfolio)) 43 | end 44 | end 45 | 46 | describe 'technologies#destroy' do 47 | it 'Allows user to delete project' do 48 | post :create, params: { portfolio_id: portfolio.id, 49 | technology: valid_attributes } 50 | delete :destroy, params: { portfolio_id: portfolio.id, 51 | id: portfolio.technologies.first.id } 52 | expect(portfolio.technologies.all.count).to eq(0) 53 | end 54 | it 'Redirects to technologies view' do 55 | post :create, params: { portfolio_id: portfolio.id, 56 | technology: valid_attributes } 57 | delete :destroy, params: { portfolio_id: portfolio.id, 58 | id: portfolio.technologies.first.id } 59 | expect(response).to redirect_to(portfolio_technologies_path(portfolio)) 60 | end 61 | end 62 | 63 | end 64 | -------------------------------------------------------------------------------- /spec/controllers/home_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe HomeController, type: :controller do 4 | 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories.rb: -------------------------------------------------------------------------------- 1 | require 'faker' 2 | 3 | FactoryGirl.define do 4 | factory :job_application do 5 | first_contact_date "2017-12-26" 6 | company_name "MyString" 7 | company_website "MyString" 8 | job_location "MyString" 9 | enthusiasm "MyString" 10 | job_title "MyString" 11 | job_link "MyString" 12 | referral "MyString" 13 | referral_type "MyString" 14 | status "MyString" 15 | industry "MyString" 16 | notes "MyText" 17 | end 18 | factory :about do 19 | portfolio nil 20 | about_me "MyText" 21 | location "MyString" 22 | about_me_brief "MyString" 23 | end 24 | factory :portfolio_header do 25 | portfolio nil 26 | header_one "MyString" 27 | header_two "MyString" 28 | cover_image "MyString" 29 | avatar_image "MyString" 30 | end 31 | factory :technology do 32 | name "MyString" 33 | portfolio nil 34 | years_exp 1 35 | proficiency 1 36 | show_years_exp false 37 | show_proficiency false 38 | end 39 | factory :portfolio do 40 | url "myurl" 41 | color_one '#ffffff' 42 | color_two '#ffffff' 43 | color_three '#ffffff' 44 | color_four '#ffffff' 45 | font_color_one '#ffffff' 46 | font_color_two '#ffffff' 47 | theme 'default' 48 | user 1 49 | id 1 50 | end 51 | factory :user do 52 | email { Faker::Internet.email } 53 | password "password" 54 | password_confirmation "password" 55 | # confirmed_at Date.today 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /spec/fixtures/images/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/spec/fixtures/images/test.jpg -------------------------------------------------------------------------------- /spec/models/about_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe About, type: :model do 4 | let(:user) { FactoryGirl.create(:user) } 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: user) } 6 | let(:attributes) do 7 | { about_me: 'testing title', 8 | about_me_brief: 'exiting stuff', 9 | location: 'here', 10 | portfolio_id: portfolio.id, 11 | email: 'myemail', 12 | github: '', 13 | linkedin: '', 14 | facebook: '', 15 | twitter: '', 16 | website: '' } 17 | end 18 | 19 | describe '#create' do 20 | it 'creates new about' do 21 | About.create(attributes) 22 | expect(About.all.count).to eq(1) 23 | end 24 | end 25 | 26 | describe '#update' do 27 | let(:about) { About.create(attributes) } 28 | it 'updates a about' do 29 | about.update(about_me: 'updated') 30 | expect(About.first.about_me).to eq('updated') 31 | end 32 | end 33 | 34 | describe '#about_me' do 35 | it do 36 | should validate_length_of(:about_me) 37 | .is_at_most(2000) 38 | end 39 | end 40 | 41 | describe '#about_me_brief' do 42 | it do 43 | should validate_length_of(:about_me_brief) 44 | .is_at_most(150) 45 | end 46 | end 47 | 48 | describe '#portfolio' do 49 | it { should belong_to(:portfolio) } 50 | end 51 | 52 | describe '#linkedin' do 53 | is_valid_url(:linkedin, About.new) 54 | it do 55 | should validate_length_of(:linkedin) 56 | .is_at_most(100) 57 | end 58 | end 59 | 60 | describe '#github' do 61 | is_valid_url(:github, About.new) 62 | it do 63 | should validate_length_of(:github) 64 | .is_at_most(100) 65 | end 66 | end 67 | 68 | describe '#twitter' do 69 | is_valid_url(:twitter, About.new) 70 | it do 71 | should validate_length_of(:twitter) 72 | .is_at_most(100) 73 | end 74 | end 75 | 76 | describe '#facebook' do 77 | is_valid_url(:facebook, About.new) 78 | it do 79 | should validate_length_of(:facebook) 80 | .is_at_most(100) 81 | end 82 | end 83 | 84 | describe '#website' do 85 | is_valid_url(:website, About.new) 86 | it do 87 | should validate_length_of(:website) 88 | .is_at_most(100) 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /spec/models/job_application_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe JobApplication, type: :model do 4 | let(:user) { FactoryGirl.create(:user) } 5 | let(:valid_attributes) do 6 | { first_contact_date: '2017-08-04', 7 | company_name: 'The First Order', 8 | job_location: 'Remote', 9 | enthusiasm: 'high', 10 | job_title: 'Supreme Leader', 11 | referral: 'Snoke', 12 | referral_type: 'mentor', 13 | status: 'applied', 14 | industry: 'ruling the galaxy' } 15 | end 16 | 17 | describe '#create' do 18 | it 'creates new project' do 19 | user.job_applications.create(valid_attributes) 20 | expect(user.job_applications.all.count).to eq(1) 21 | end 22 | end 23 | 24 | describe '#update' do 25 | let(:job_application) { user.job_applications.create(valid_attributes) } 26 | it 'updates a project' do 27 | job_application.update(company_name: 'Rebal Alliance') 28 | expect(user.job_applications.first.company_name).to eq('Rebal Alliance') 29 | end 30 | end 31 | 32 | describe '#user' do 33 | it { should belong_to(:user) } 34 | end 35 | 36 | describe '#enthusiasm' do 37 | it do 38 | should validate_inclusion_of(:enthusiasm) 39 | .in_array(%w[high medium low]) 40 | end 41 | end 42 | 43 | describe '#status' do 44 | it do 45 | should validate_inclusion_of(:status) 46 | .in_array(%w[researching applied interviewing rejected offer]) 47 | end 48 | end 49 | 50 | describe '#referral_type' do 51 | it do 52 | should validate_inclusion_of(:referral_type) 53 | .in_array(['cold outreach', 'mentor', 'personal connection', 'new connection', 'career website']) 54 | end 55 | end 56 | 57 | describe '#company_name' do 58 | it do 59 | should validate_length_of(:company_name) 60 | .is_at_most(100) 61 | end 62 | end 63 | 64 | describe '#company_website' do 65 | it do 66 | should validate_length_of(:company_website) 67 | .is_at_most(100) 68 | end 69 | end 70 | 71 | describe '#job_location' do 72 | it do 73 | should validate_length_of(:job_location) 74 | .is_at_most(100) 75 | end 76 | end 77 | 78 | describe '#job_title' do 79 | it do 80 | should validate_length_of(:job_title) 81 | .is_at_most(100) 82 | end 83 | end 84 | 85 | describe '#referral' do 86 | it do 87 | should validate_length_of(:referral) 88 | .is_at_most(100) 89 | end 90 | end 91 | 92 | describe '#industry' do 93 | it do 94 | should validate_length_of(:industry) 95 | .is_at_most(100) 96 | end 97 | end 98 | 99 | describe '#notes' do 100 | it do 101 | should validate_length_of(:notes) 102 | .is_at_most(1000) 103 | end 104 | end 105 | 106 | describe '#job_link' do 107 | it do 108 | should validate_length_of(:job_link) 109 | .is_at_most(250) 110 | end 111 | end 112 | end 113 | -------------------------------------------------------------------------------- /spec/models/portfolio_header_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe PortfolioHeader, type: :model do 4 | let(:user) { FactoryGirl.create(:user) } 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: user) } 6 | let(:attributes) do 7 | { header_one: 'testing title', 8 | header_two: 'exiting stuff', 9 | header_two_color: '#ffffff', 10 | header_one_color: '#ffffff', 11 | portfolio_id: portfolio.id } 12 | end 13 | 14 | describe '#create' do 15 | it 'creates new portfolio_header' do 16 | PortfolioHeader.create(attributes) 17 | expect(PortfolioHeader.all.count).to eq(1) 18 | end 19 | it 'uploads image using CoverImageUploader' do 20 | image = fixture_file_upload('images/test.jpg') 21 | record = PortfolioHeader.new(attributes) 22 | record.cover_image = image 23 | record.save 24 | expect(PortfolioHeader.first.cover_image.is_a?(CoverImageUploader)).to eq(true) 25 | end 26 | it 'uploads image using AvatarImageUploader' do 27 | image = fixture_file_upload('images/test.jpg') 28 | record = PortfolioHeader.new(attributes) 29 | record.avatar_image = image 30 | record.save 31 | expect(PortfolioHeader.first.avatar_image.is_a?(AvatarImageUploader)).to eq(true) 32 | end 33 | end 34 | 35 | describe '#update' do 36 | let(:portfolio_header) { PortfolioHeader.create(attributes) } 37 | it 'updates a portfolio_header' do 38 | portfolio_header.update(header_one: 'updated') 39 | expect(PortfolioHeader.first.header_one).to eq('updated') 40 | end 41 | end 42 | 43 | describe '#header_one' do 44 | it do 45 | should validate_length_of(:header_one) 46 | .is_at_most(100) 47 | end 48 | end 49 | 50 | describe '#header_two' do 51 | it do 52 | should validate_length_of(:header_two) 53 | .is_at_most(100) 54 | end 55 | end 56 | 57 | describe '#header_two_color' do 58 | is_valid_css_hex_color(:header_two_color, PortfolioHeader.new) 59 | end 60 | 61 | describe '#header_one_color' do 62 | is_valid_css_hex_color(:header_one_color, PortfolioHeader.new) 63 | end 64 | 65 | describe '#portfolio' do 66 | it { should belong_to(:portfolio) } 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /spec/models/portfolio_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Portfolio, type: :model do 4 | let(:user) { FactoryGirl.create(:user) } 5 | let(:attributes) do 6 | { url: 'testing', 7 | color_one: '#ffffff', 8 | color_two: '#ffffff', 9 | color_three: '#ffffff', 10 | color_four: '#ffffff', 11 | theme: 'default' } 12 | end 13 | 14 | describe 'Create Portfolio' do 15 | it 'creates a new portfolio' do 16 | user.portfolios.create(attributes) 17 | expect(user.portfolios.first.url).to eq('testing') 18 | end 19 | end 20 | 21 | describe 'Update Portfolio' do 22 | let(:portfolio) { user.portfolios.create(attributes) } 23 | it 'edits portfolio URL' do 24 | portfolio.update(url: 'test') 25 | expect(user.portfolios.first.url).to eq('test') 26 | end 27 | end 28 | 29 | describe '#user' do 30 | it { should belong_to(:user) } 31 | end 32 | 33 | describe '#url' do 34 | it { should validate_presence_of(:url) } 35 | it { should validate_uniqueness_of(:url) } 36 | it do 37 | should validate_length_of(:url) 38 | .is_at_least(3) 39 | end 40 | it 'should only containe lowercase alphanumeric characters' do 41 | record = Portfolio.new 42 | invalid_characters = %w[! @ A B # $ % ^ & * ( ) = + / \ { } [ ] < > ' " ` ~] 43 | invalid_characters.each do |char| 44 | record.url = "test#{char}" 45 | record.valid? 46 | expect(record.errors[:url]).to eq(['must only contain lowercase alphanumeric characters, hyphens, or underscores']) 47 | end 48 | record.url = 'myurl' 49 | record.valid? 50 | expect(record.errors[:url]).to eq([]) 51 | end 52 | end 53 | 54 | describe '#color_one' do 55 | is_valid_css_hex_color(:color_one, Portfolio.new) 56 | end 57 | 58 | describe '#color_two' do 59 | is_valid_css_hex_color(:color_two, Portfolio.new) 60 | end 61 | 62 | describe '#color_three' do 63 | is_valid_css_hex_color(:color_three, Portfolio.new) 64 | end 65 | 66 | describe '#color_three' do 67 | is_valid_css_hex_color(:color_four, Portfolio.new) 68 | end 69 | 70 | describe '#theme' do 71 | it do 72 | should validate_inclusion_of(:theme) 73 | .in_array(Themes.array) 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /spec/models/project_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Project, type: :model do 4 | let(:user) { FactoryGirl.create(:user) } 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: user) } 6 | let(:project_input) do 7 | { title: 'My title', 8 | description: 'So many words', 9 | role: 'supreme leader', 10 | link: 'the-fun-place', 11 | tech: 'mostly interent explorer', 12 | order: 1 } 13 | end 14 | let(:project) { portfolio.projects.new(project_input) } 15 | 16 | describe '#create' do 17 | it 'creates new project' do 18 | portfolio.projects.create(project_input) 19 | expect(portfolio.projects.all.count).to eq(1) 20 | end 21 | it 'uploads image using ImageUploader' do 22 | image = fixture_file_upload('images/test.jpg') 23 | portfolio.projects.create(image: image) 24 | expect(portfolio.projects.first.image.is_a?(ImageUploader)).to eq(true) 25 | end 26 | end 27 | 28 | describe '#update' do 29 | let(:project) { portfolio.projects.create(project_input) } 30 | it 'updates a project' do 31 | project.update(title: 'updated') 32 | expect(portfolio.projects.first.title).to eq('updated') 33 | end 34 | end 35 | 36 | describe '#portfolio' do 37 | it { should belong_to(:portfolio) } 38 | end 39 | 40 | describe '#order' do 41 | it 'validates order as a number' do 42 | record = portfolio.projects.new(project_input) 43 | record.order = '2' 44 | record.valid? 45 | expect(record.errors[:order]).to eq([]) 46 | record.order = 'two' 47 | record.valid? 48 | expect(record.errors[:order]).to eq(['is not a number']) 49 | end 50 | it 'validates order as greater than 0' do 51 | record = portfolio.projects.new(project_input) 52 | record.order = 1 53 | record.valid? 54 | expect(record.errors[:order]).to eq([]) 55 | record.order = 0 56 | record.valid? 57 | expect(record.errors[:order]).to eq(['must be greater than 0']) 58 | end 59 | it 'validates order as less than 20' do 60 | record = portfolio.projects.new(project_input) 61 | record.order = 19 62 | record.valid? 63 | expect(record.errors[:order]).to eq([]) 64 | record.order = 20 65 | record.valid? 66 | expect(record.errors[:order]).to eq(['must be less than 20']) 67 | end 68 | end 69 | 70 | describe '#link' do 71 | project_attribute_has_maximum_length_of(200, :link) 72 | end 73 | 74 | describe '#role' do 75 | project_attribute_has_maximum_length_of(200, :role) 76 | end 77 | 78 | describe '#tech' do 79 | project_attribute_has_maximum_length_of(500, :tech) 80 | end 81 | 82 | describe '#description' do 83 | project_attribute_has_maximum_length_of(2000, :description) 84 | end 85 | 86 | describe '#title' do 87 | project_attribute_has_maximum_length_of(40, :title) 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /spec/models/technology_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Technology, type: :model do 4 | let(:user) { FactoryGirl.create(:user) } 5 | let(:portfolio) { FactoryGirl.create(:portfolio, user: user) } 6 | let(:attributes) do 7 | { name: 'Ruby', 8 | years_exp: 1, 9 | proficiency: 8 } 10 | end 11 | 12 | describe '#update' do 13 | it 'creates new technology' do 14 | portfolio.technologies.create(attributes) 15 | expect(portfolio.technologies.all.count).to eq(1) 16 | end 17 | end 18 | 19 | describe '#create' do 20 | it 'updates new technology' do 21 | record = portfolio.technologies.create(attributes) 22 | record.update(name: 'updated') 23 | expect(record.name).to eq('updated') 24 | end 25 | end 26 | 27 | describe '#portfolio' do 28 | it { should belong_to(:portfolio) } 29 | end 30 | 31 | describe '#proficiency' do 32 | it { should validate_numericality_of(:proficiency) } 33 | end 34 | 35 | describe '#years_exp' do 36 | it { should validate_numericality_of(:years_exp) } 37 | end 38 | 39 | describe '#name' do 40 | it { should validate_presence_of(:name) } 41 | it do 42 | should validate_length_of(:name) 43 | .is_at_most(20) 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /spec/routing/job_applications_routing_spec.rb: -------------------------------------------------------------------------------- 1 | # require "rails_helper" 2 | # 3 | # RSpec.describe Dashboard::JobApplicationsController, type: :routing do 4 | # describe "routing" do 5 | # 6 | # it "routes to #index" do 7 | # expect(:get => "/job_applications").to route_to("job_applications#index") 8 | # end 9 | # 10 | # it "routes to #new" do 11 | # expect(:get => "/job_applications/new").to route_to("job_applications#new") 12 | # end 13 | # 14 | # it "routes to #show" do 15 | # expect(:get => "/job_applications/1").to route_to("job_applications#show", :id => "1") 16 | # end 17 | # 18 | # it "routes to #edit" do 19 | # expect(:get => "/job_applications/1/edit").to route_to("job_applications#edit", :id => "1") 20 | # end 21 | # 22 | # it "routes to #create" do 23 | # expect(:post => "/job_applications").to route_to("job_applications#create") 24 | # end 25 | # 26 | # it "routes to #update via PUT" do 27 | # expect(:put => "/job_applications/1").to route_to("job_applications#update", :id => "1") 28 | # end 29 | # 30 | # it "routes to #update via PATCH" do 31 | # expect(:patch => "/job_applications/1").to route_to("job_applications#update", :id => "1") 32 | # end 33 | # 34 | # it "routes to #destroy" do 35 | # expect(:delete => "/job_applications/1").to route_to("job_applications#destroy", :id => "1") 36 | # end 37 | # 38 | # end 39 | # end 40 | -------------------------------------------------------------------------------- /spec/support/controller_macros.rb: -------------------------------------------------------------------------------- 1 | module ControllerMacros 2 | def login_admin 3 | before(:each) do 4 | @request.env["devise.mapping"] = Devise.mappings[:admin] 5 | sign_in FactoryGirl.create(:admin) # Using factory girl as an example 6 | end 7 | end 8 | 9 | def login_user 10 | before(:each) do 11 | @request.env["devise.mapping"] = Devise.mappings[:user] 12 | user = FactoryGirl.create(:user) 13 | sign_in user 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/custom_validations.rb: -------------------------------------------------------------------------------- 1 | module CustomValidationsSpec 2 | def is_valid_css_hex_color(attribute, record) 3 | it 'is a valid CSS hex color' do 4 | record.send("#{attribute}=", '#kjhadk') 5 | record.valid? 6 | expect(record.errors[attribute]).to eq(['must be a valid CSS hex color code']) 7 | 8 | record.send("#{attribute}=", 123456) 9 | record.valid? 10 | expect(record.errors[attribute]).to eq(['must be a valid CSS hex color code']) 11 | 12 | record.send("#{attribute}=", '#123456') 13 | record.valid? 14 | expect(record.errors[attribute]).to eq([]) 15 | end 16 | end 17 | 18 | def is_valid_url(attribute, record) 19 | it 'is a valid URL' do 20 | record.send("#{attribute}=", 'kjhadk') 21 | record.valid? 22 | expect(record.errors[attribute]).to eq(["must be a valid URL (URLs must start with 'http://')"]) 23 | 24 | record.send("#{attribute}=", 'www.facebook.com') 25 | record.valid? 26 | expect(record.errors[attribute]).to eq(["must be a valid URL (URLs must start with 'http://')"]) 27 | 28 | record.send("#{attribute}=", 'http://www.facebook.com') 29 | record.valid? 30 | expect(record.errors[attribute]).to eq([]) 31 | end 32 | end 33 | 34 | def project_attribute_has_maximum_length_of(length, attribute) 35 | let(:user) { FactoryGirl.create(:user) } 36 | let(:portfolio) { FactoryGirl.create(:portfolio, user: user) } 37 | let(:attribute) do 38 | { header_one: 'testing title', 39 | header_two: 'exiting stuff', 40 | header_two_color: '#ffffff', 41 | header_one_color: '#ffffff', 42 | portfolio_id: portfolio.id } 43 | end 44 | 45 | short_string = build_string(length) 46 | long_string = build_string(length + 1) 47 | 48 | it "has a maximum length of #{length}" do 49 | record = portfolio.projects.new(project_input) 50 | record.send("#{attribute}=", short_string) 51 | record.valid? 52 | expect(record.errors[attribute]).to eq([]) 53 | record.send("#{attribute}=", long_string) 54 | record.valid? 55 | expect(record.errors[attribute].length).to eq(1) 56 | end 57 | end 58 | 59 | def build_string(length) 60 | string = '' 61 | length.times do 62 | string << 'a' 63 | end 64 | string 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/tmp/.keep -------------------------------------------------------------------------------- /vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-wendell/my_dev_portal/1af14e5922880aeac9b7808aae88cf626e9b3165/vendor/.keep --------------------------------------------------------------------------------