diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..f9653486b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: "bundler" + directory: "/" + target-branch: "develop" + schedule: + interval: "daily" + commit-message: + prefix: "build(deps): " + + - package-ecosystem: "npm" + directory: "/website" + target-branch: "develop" + schedule: + interval: "daily" + commit-message: + prefix: "build(deps): " diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b340e8c3..7208272d9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,6 +12,8 @@ on: branches: - master - develop + - '[0-9].[0-9]' + - '[0-9].[0-9].[0-9]' jobs: build: diff --git a/CHECKS b/CHECKS index 24d7a521f..00dbaece8 100644 --- a/CHECKS +++ b/CHECKS @@ -1,4 +1,4 @@ WAIT=10 -ATTEMPTS=300 +ATTEMPTS=100 /users/sign_in Sign in to diff --git a/Gemfile b/Gemfile index b80ae29ee..8c0e172c7 100644 --- a/Gemfile +++ b/Gemfile @@ -25,6 +25,8 @@ gem 'turbolinks', '~> 5' # gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production gem 'redis', '~> 4.0' +# CORS support +gem 'rack-cors' # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' @@ -65,6 +67,8 @@ gem 'jquery-ui-rails' gem 'selectize-rails' gem 'highcharts-rails', '~> 6.0' gem 'bootstrap', '~> 4.3.1' +gem 'fullcalendar-rails' +gem 'momentjs-rails' # Markdown parsing gem 'redcarpet' @@ -76,7 +80,7 @@ gem 'audited', '~> 4.7' # Background job processing gem 'sidekiq', '< 7' -gem 'sidekiq-cron', '~> 1.1' +gem 'sidekiq-cron', github: 'codeRIT/sidekiq-cron', branch: 'master' # Misc support gems gem 'rails-settings-cached', '~> 0.7.2' @@ -111,8 +115,8 @@ end group :test do gem 'test-unit', '~> 3.0' - gem 'shoulda', '~> 3.5' - gem 'shoulda-matchers', '~> 2.0' + gem 'shoulda', '~> 4.0.0' + gem 'shoulda-matchers', '~> 4.4.0' gem 'minitest-reporters' gem 'valid_attribute' gem 'factory_bot_rails' diff --git a/Gemfile.lock b/Gemfile.lock index f310deea9..344bc1684 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,12 @@ +GIT + remote: https://github.com/codeRIT/sidekiq-cron.git + revision: 571d7d74d2828aea2f55381a83f73ac3450e8819 + branch: master + specs: + sidekiq-cron (1.2.0) + fugit (~> 1.1) + sidekiq (>= 4.2.1) + GEM remote: https://rubygems.org/ specs: @@ -129,7 +138,7 @@ GEM dotenv (= 2.7.5) railties (>= 3.2, < 6.1) errbase (0.2.0) - erubi (1.9.0) + erubi (1.10.0) erubis (2.7.0) et-orbi (1.2.4) tzinfo @@ -149,9 +158,13 @@ GEM font-awesome-rails (4.7.0.5) railties (>= 3.2, < 6.1) formatador (0.2.5) - fugit (1.3.6) + fugit (1.4.2) et-orbi (~> 1.1, >= 1.1.8) - raabro (~> 1.3) + raabro (~> 1.4) + fullcalendar-rails (3.9.0.0) + jquery-rails (>= 4.0.5, < 5.0.0) + jquery-ui-rails (>= 5.0.2) + momentjs-rails (>= 2.9.0) globalid (0.4.2) activesupport (>= 4.2.0) groupdate (5.0.0) @@ -205,7 +218,7 @@ GEM rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) - loofah (2.7.0) + loofah (2.8.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) lumberjack (1.2.6) @@ -226,6 +239,8 @@ GEM builder minitest (>= 5.0) ruby-progressbar + momentjs-rails (2.20.1) + railties (>= 3.1) msgpack (1.3.3) multi_json (1.15.0) multi_xml (0.6.0) @@ -233,7 +248,7 @@ GEM mustache (1.1.1) mysql2 (0.5.3) nenv (0.3.0) - nio4r (2.5.3) + nio4r (2.5.4) nokogiri (1.10.10) mini_portile2 (~> 2.4.0) notiffany (0.1.3) @@ -267,8 +282,10 @@ GEM public_suffix (4.0.5) puma (4.3.5) nio4r (~> 2.0) - raabro (1.3.1) + raabro (1.4.0) rack (2.2.3) + rack-cors (1.1.1) + rack (>= 2.0.0) rack-protection (2.0.8.1) rack rack-test (1.1.0) @@ -313,7 +330,7 @@ GEM rb-inotify (0.10.1) ffi (~> 1.0) redcarpet (3.5.0) - redis (4.2.1) + redis (4.2.5) regexp_parser (1.7.1) responders (3.0.1) actionpack (>= 5.0) @@ -355,20 +372,16 @@ GEM ruby_http_client (~> 3.4) sexp_processor (4.15.0) shellany (0.0.1) - shoulda (3.5.0) - shoulda-context (~> 1.0, >= 1.0.1) - shoulda-matchers (>= 1.4.1, < 3.0) - shoulda-context (1.2.2) - shoulda-matchers (2.8.0) - activesupport (>= 3.0.0) - sidekiq (6.0.7) + shoulda (4.0.0) + shoulda-context (~> 2.0) + shoulda-matchers (~> 4.0) + shoulda-context (2.0.0) + shoulda-matchers (4.4.1) + activesupport (>= 4.2.0) + sidekiq (6.1.3) connection_pool (>= 2.2.2) rack (~> 2.0) - rack-protection (>= 2.0.0) - redis (>= 4.1.0) - sidekiq-cron (1.2.0) - fugit (~> 1.1) - sidekiq (>= 4.2.1) + redis (>= 4.2.0) simple_form (5.0.2) actionpack (>= 5.0) activemodel (>= 5.0) @@ -386,7 +399,7 @@ GEM sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.1) + sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) @@ -402,7 +415,7 @@ GEM turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) - tzinfo (1.2.7) + tzinfo (1.2.9) thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) @@ -451,6 +464,7 @@ DEPENDENCIES factory_bot_rails file_validators font-awesome-rails (~> 4.0) + fullcalendar-rails groupdate guard guard-minitest @@ -461,11 +475,13 @@ DEPENDENCIES jquery-ui-rails listen (>= 3.0.5, < 3.2) minitest-reporters + momentjs-rails mustache (~> 1.0) mysql2 (>= 0.4.4, < 0.6.0) omniauth-mlh (~> 0.4.1) omniauth-rails_csrf_protection puma (~> 4.3) + rack-cors rails (~> 5.2.4.4) rails-controller-testing rails-settings-cached (~> 0.7.2) @@ -479,10 +495,10 @@ DEPENDENCIES selectize-rails selenium-webdriver sendgrid-actionmailer - shoulda (~> 3.5) - shoulda-matchers (~> 2.0) + shoulda (~> 4.0.0) + shoulda-matchers (~> 4.4.0) sidekiq (< 7) - sidekiq-cron (~> 1.1) + sidekiq-cron! simple_form simple_spark simplecov diff --git a/README.md b/README.md index 186e6619d..092f64d71 100644 --- a/README.md +++ b/README.md @@ -108,14 +108,14 @@ $ bin/rails s # short for bin/rails server 6. Visit http://localhost:3000/apply, create an account, and complete an application -7. In another bash window, promote your user to an admin +7. In another bash window, promote your user to a director ```bash $ cd hackathon-manager $ bin/rails c # short for bin/rails console # Wait for the console to start... Loading development environment (Rails 5.1.1) -irb(main):001:0> User.last.update_attribute(:role, :admin) +irb(main):001:0> User.last.update_attribute(:role, :director) ``` 8. Visit http://localhost:3000/manage and set up the hackathon as needed diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 8a917f699..d12456d3d 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -21,3 +21,6 @@ //= require_directory . //= require_directory ./channels //= require ./vendor/simplemde.min.js +//= require moment +//= require fullcalendar +//= require fullcalendar/locale-all diff --git a/app/assets/javascripts/events.js b/app/assets/javascripts/events.js new file mode 100644 index 000000000..fbe50362b --- /dev/null +++ b/app/assets/javascripts/events.js @@ -0,0 +1,43 @@ +function eventCalendar() { + return $('#calendar').fullCalendar({ + defaultView: 'listYear', + buttonText: { + today: 'Today' + }, + eventRender: function (event, element, view) { + element.find('.fc-event-dot').css('display', 'none'); + if(event.description) { + element.find('.fc-list-item-title').append('
' + event.description + ''); + } + if (event.location) { + element.find('.fc-list-item-title').append('Location: ' + event.location + ''); + } + if (event.category) { + element.find('.fc-list-item-title').append('Category: ' + event.category + ''); + } + }, + events: { + url: '/manage/events.json', + success: function (response) { + // due to "end" being a keyword in ruby and what fullcalender uses it is stored as finish and than it is + // converted to "end" when sending it to fullcalendar + response = JSON.parse(JSON.stringify(response).split('"finish":').join('"end":')); + return response; + } + }, + eventClick: function (info) { + window.location = 'events/' + info.id; + }, + height: 'auto', + }); +} + +function clearCalendar() { + $('#calendar').fullCalendar('delete'); + $('#calendar').html(''); +} + +document.addEventListener('turbolinks:load', function () { + eventCalendar(); +}); +document.addEventListener('turbolinks:before-cache', clearCalendar); diff --git a/app/assets/javascripts/manage/lib/dashboardMap.js b/app/assets/javascripts/manage/lib/dashboardMap.js new file mode 100644 index 000000000..0debe2451 --- /dev/null +++ b/app/assets/javascripts/manage/lib/dashboardMap.js @@ -0,0 +1,13 @@ +document.addEventListener('turbolinks:load', function () { + $('.map-button').click(function (){ + var map = $('#map'); + if(map.is(':visible')){ + map.hide(); + $(this).html('Show Map'); + } + else{ + map.show(); + $(this).html('Hide Map'); + } + }); +}); diff --git a/app/assets/javascripts/manage/lib/setupDataTables.js b/app/assets/javascripts/manage/lib/setupDataTables.js index f9418bc3c..2403217db 100644 --- a/app/assets/javascripts/manage/lib/setupDataTables.js +++ b/app/assets/javascripts/manage/lib/setupDataTables.js @@ -124,7 +124,7 @@ var setupDataTables = function () { ] }); - $('.datatable.stats-mlhinfo-applied').DataTable({ + $('.datatable.stats-info-applied').DataTable({ order: [1, 'asc'], columns: [ { orderable: true, data: 'id', visible: false }, @@ -136,7 +136,7 @@ var setupDataTables = function () { ] }); - $('.datatable.stats-mlhinfo-checkedin').DataTable({ + $('.datatable.stats-info-checkedin').DataTable({ order: [1, 'asc'], columns: [ { orderable: true, data: 'id', visible: false }, diff --git a/app/assets/javascripts/validate.js b/app/assets/javascripts/validate.js index aa37eb8ab..d61bbcb79 100644 --- a/app/assets/javascripts/validate.js +++ b/app/assets/javascripts/validate.js @@ -18,8 +18,8 @@ document.addEventListener('turbolinks:load', function() { switch (types[i]) { case 'presence': if (!value || $.trim(value).length < 1) { - if ($(this).parents('.agreement_input')) { - notify('.agreement_input', 'Please read & accept'); + if ($(this).hasClass("agreement_input")) { + notify($(this).parent(), 'Please read & accept'); } else { notify(this, 'Missing Information'); } @@ -74,7 +74,9 @@ document.addEventListener('turbolinks:load', function() { .fadeOut(200, function() { $(this).remove(); }); - $(".agreement_input") + // this removes the notification for agreements + $(this) + .parent() .parent() .removeClass('field_with_errors') .find('.error') diff --git a/app/assets/stylesheets/forms/_forms.sass b/app/assets/stylesheets/forms/_forms.sass index 6d26169c0..819306334 100644 --- a/app/assets/stylesheets/forms/_forms.sass +++ b/app/assets/stylesheets/forms/_forms.sass @@ -73,6 +73,8 @@ hr @include css4 color: var(--grey) .error + display: inline-block + width: 100% @include css4 background: var(--input--error--background) color: var(--input--error--text) diff --git a/app/assets/stylesheets/manage.sass b/app/assets/stylesheets/manage.sass index 970171e2d..8e7464574 100644 --- a/app/assets/stylesheets/manage.sass +++ b/app/assets/stylesheets/manage.sass @@ -6,6 +6,7 @@ @import general/variables @import general/css4 @import manage/autocomplete +@import manage/events $grey-dark: #555 $grey-med: #999 @@ -15,6 +16,7 @@ $grey-med: #999 @import vendor/datatables.min @import selectize @import selectize.default +@import fullcalendar .icon-space-r margin-right: 0.5em @@ -57,6 +59,16 @@ $grey-med: #999 text-align: center overflow: auto width: 100% + @media (max-width: 768px) + display: none + +.map-button + display: none + @media (max-width: 768px) + display: block + +.narrow-icon + width: 40px .dashboard-container-title border-bottom: 3px solid #e5e5e5 @@ -69,21 +81,25 @@ $grey-med: #999 vertical-align: top position: absolute z-index: 1 - background: rgba(#ffffff,0.86) + background: rgba(#ffffff, 0.86) margin-left: 33px padding: 0 6% height: 136px + h3 color: $black font-weight: 500 margin: 1.2em 0 0 + p font-size: 14px margin: 0.5em 0 1.2em + &.double-metrics h3 margin-top: 0.45em font-size: 21px + p font-size: 13px margin-top: 0.3em @@ -92,6 +108,7 @@ $grey-med: #999 list-style: none margin: 0 0 10px padding: 0 + li margin: 0 padding: 2px @@ -111,7 +128,8 @@ $grey-med: #999 height: calc(100% + 20px) .editor-toolbar.fullscreen - z-index: 1031 // in front of the navbar + z-index: 1031 +// in front of the navbar /* * Mobile nav @@ -126,6 +144,7 @@ $grey-med: #999 .navbar-mobile-toggle--active background: #eeeeee + .fa color: black !important @@ -137,6 +156,10 @@ $grey-med: #999 height: calc(100vh - 2.25rem) overflow: scroll +.calendar-list + width: 100% + min-width: 500px + margin: auto /* * Datatable changes diff --git a/app/assets/stylesheets/manage/events.sass b/app/assets/stylesheets/manage/events.sass new file mode 100644 index 000000000..1d4ec926a --- /dev/null +++ b/app/assets/stylesheets/manage/events.sass @@ -0,0 +1,9 @@ +.fc-list-item + cursor: pointer !important + +.event_start select:first-child, .event_finish select:first-child + margin-left: 0 !important + +.event_start select:last-child, .event_finish select:last-child + margin-right: 0 !important + diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb new file mode 100644 index 000000000..30c5b00ba --- /dev/null +++ b/app/controllers/events_controller.rb @@ -0,0 +1,7 @@ +class EventsController < ApplicationController + respond_to :json + + def show + render json: Event.all + end +end diff --git a/app/controllers/manage/events_controller.rb b/app/controllers/manage/events_controller.rb new file mode 100644 index 000000000..cb89fc3e5 --- /dev/null +++ b/app/controllers/manage/events_controller.rb @@ -0,0 +1,54 @@ +class Manage::EventsController < Manage::ApplicationController + before_action :require_director + respond_to :html, :json + + def index + @start_date = HackathonConfig['event_start_date'] + respond_to do |format| + format.html + format.json { render json: Event.all } + end + end + + def new + @event = ::Event.new + end + + def create + @event = ::Event.new(event_params) + if @event.save + redirect_to(manage_events_path) + else + render('new') + end + end + + def show + @event = Event.find_by_id(params[:id]) + respond_with(:manage, @event) + end + + def update + @event = Event.find_by_id(params[:id]) + if @event.update(event_params) + redirect_to(manage_events_path) + else + render('show') + end + end + + def destroy + @event = Event.find_by_id(params[:id]) + if @event.destroy + redirect_to(manage_events_path) + else + render('show') + end + end + + def event_params + params.require(:event).permit( + :title, :description, :location, :category, :start, :finish + ) + end +end diff --git a/app/controllers/manage/stats_controller.rb b/app/controllers/manage/stats_controller.rb index 09deb7526..426423c24 100644 --- a/app/controllers/manage/stats_controller.rb +++ b/app/controllers/manage/stats_controller.rb @@ -15,11 +15,11 @@ def attendee_sponsor_info_datatable render json: AttendeeSponsorInfoDatatable.new(params, view_context: view_context) end - def mlh_applied_datatable - render json: MLHAppliedDatatable.new(params, view_context: view_context) + def applied_datatable + render json: AppliedDatatable.new(params, view_context: view_context) end - def mlh_checked_in_datatable - render json: MLHCheckedInDatatable.new(params, view_context: view_context) + def checked_in_datatable + render json: CheckedInDatatable.new(params, view_context: view_context) end end diff --git a/app/controllers/manage/users_controller.rb b/app/controllers/manage/users_controller.rb index e5d743166..6ef31a54f 100644 --- a/app/controllers/manage/users_controller.rb +++ b/app/controllers/manage/users_controller.rb @@ -1,6 +1,6 @@ class Manage::UsersController < Manage::ApplicationController before_action :require_director - before_action :find_user, only: [:show, :edit, :update, :destroy] + before_action :find_user, only: [:show, :edit, :update, :reset_password, :destroy] respond_to :html, :json @@ -16,6 +16,14 @@ def staff_datatable render json: StaffDatatable.new(params, view_context: view_context) end + def reset_password + new_password = Devise.friendly_token(50) + @user.reset_password(new_password, new_password) + @user.send_reset_password_instructions + flash[:notice] = t(:reset_password_success, scope: 'pages.manage.users.edit', full_name: @user.full_name) + respond_with(:manage, @user, location: manage_users_path) + end + def show respond_with(:manage, @user) end diff --git a/app/controllers/questionnaires_controller.rb b/app/controllers/questionnaires_controller.rb index f8520ca04..a1c5cf1f8 100644 --- a/app/controllers/questionnaires_controller.rb +++ b/app/controllers/questionnaires_controller.rb @@ -144,7 +144,7 @@ def questionnaire_params params.require(:questionnaire).permit( :email, :experience, :gender, :date_of_birth, :interest, :school_id, :school_name, :major, :level_of_study, - :shirt_size, :dietary_restrictions, :special_needs, :international, + :shirt_size, :dietary_restrictions, :special_needs, :international, :country, :portfolio_url, :vcs_url, :bus_captain_interest, :phone, :can_share_info, :travel_not_from_school, :travel_location, :graduation_year, :race_ethnicity, :resume, :delete_resume, :why_attend, agreement_ids: [] diff --git a/app/datatables/mlh_applied_datatable.rb b/app/datatables/applied_datatable.rb similarity index 94% rename from app/datatables/mlh_applied_datatable.rb rename to app/datatables/applied_datatable.rb index 7da2d25c4..9fb418866 100644 --- a/app/datatables/mlh_applied_datatable.rb +++ b/app/datatables/applied_datatable.rb @@ -1,4 +1,4 @@ -class MLHAppliedDatatable < ApplicationDatatable +class AppliedDatatable < ApplicationDatatable def_delegators :@view, :link_to, :manage_stats_path, :bold, :display_datetime def view_columns diff --git a/app/datatables/mlh_checked_in_datatable.rb b/app/datatables/checked_in_datatable.rb similarity index 94% rename from app/datatables/mlh_checked_in_datatable.rb rename to app/datatables/checked_in_datatable.rb index 7524b2c01..3aadb6c6c 100644 --- a/app/datatables/mlh_checked_in_datatable.rb +++ b/app/datatables/checked_in_datatable.rb @@ -1,4 +1,4 @@ -class MLHCheckedInDatatable < ApplicationDatatable +class CheckedInDatatable < ApplicationDatatable def_delegators :@view, :link_to, :manage_stats_path, :bold, :display_datetime def view_columns diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index ef1d03cf2..779e2c9cb 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -23,8 +23,7 @@ def incomplete_reminder_email(user_id) def rsvp_reminder_email(user_id) @user = User.find_by_id(user_id) - return if @user.blank? || !@user.questionnaire.acc_status == "accepted" || Time.now.in_time_zone.to_date > Date.parse(HackathonConfig["event_start_date"]).in_time_zone.to_date - + return if @user.blank? || @user.questionnaire.blank? || @user.questionnaire.acc_status != "accepted" || Time.now.in_time_zone.to_date > Date.parse(HackathonConfig["event_start_date"]).in_time_zone.to_date Message.queue_for_trigger("questionnaire.rsvp_reminder", @user.id) end end diff --git a/app/models/event.rb b/app/models/event.rb new file mode 100644 index 000000000..e5dde9abf --- /dev/null +++ b/app/models/event.rb @@ -0,0 +1,33 @@ +class Event < ApplicationRecord + validates_presence_of :title, :start + + validate :finish_before_start + + def finish_before_start + return if finish.nil? + unless finish > start + errors.add(:finish, 'time must be after start time') + end + end + + def description=(value) + if value.blank? + value = nil + end + super value + end + + def location=(value) + if value.blank? + value = nil + end + super value + end + + def category=(value) + if value.blank? + value = nil + end + super value + end +end diff --git a/app/models/questionnaire.rb b/app/models/questionnaire.rb index ad8c2f488..31b14dcb0 100644 --- a/app/models/questionnaire.rb +++ b/app/models/questionnaire.rb @@ -3,7 +3,6 @@ class Questionnaire < ApplicationRecord include ActiveModel::Dirty include DeletableAttachment - before_validation :consolidate_school_names before_validation :clean_for_non_rsvp before_validation :clean_negative_special_needs @@ -24,6 +23,7 @@ class Questionnaire < ApplicationRecord validates_presence_of :phone, :date_of_birth, :school_id, :experience, :shirt_size, :interest validates_presence_of :gender, :major, :level_of_study, :graduation_year, :race_ethnicity + validates :country, presence: { message: %[information is missing from application. Please update your Application] } DIETARY_SPECIAL_NEEDS_MAX_LENGTH = 500 validates_length_of :dietary_restrictions, maximum: DIETARY_SPECIAL_NEEDS_MAX_LENGTH @@ -121,6 +121,203 @@ class Questionnaire < ApplicationRecord "Other" ].freeze + POSSIBLE_COUNTRIES = [ + "United States", + "Afghanistan", + "Albania", + "Algeria", + "Andorra", + "Angola", + "Antigua and Barbuda", + "Argentina", + "Armenia", + "Australia", + "Austria", + "Azerbaijan", + "Bahamas", + "Bahrain", + "Bangladesh", + "Barbados", + "Belarus", + "Belgium", + "Belize", + "Benin", + "Bhutan", + "Bolivia", + "Bosnia and Herzegovina", + "Botswana", + "Brazil", + "Brunei", + "Bulgaria", + "Burkina Faso", + "Burundi", + "Cambodia", + "Cameroon", + "Canada", + "Cape Verde", + "Central African Republic", + "Chad", + "Chile", + "China", + "Colombia", + "Comoros", + "Congo, Democratic Republic of the Congo", + "Congo, Republic of the", + "Costa Rica", + "Cote d'Ivoire (Ivory Coast)", + "Croatia", + "Cuba", + "Cyprus", + "Czech Republic", + "Denmark", + "Djibouti", + "Dominica", + "Dominican Republic", + "Timor-Leste (East Timor)", + "Ecuador", + "Egypt", + "El Salvador", + "Equatorial Guinea", + "Eritrea", + "Estonia", + "Ethiopia", + "Fiji", + "Finland", + "France", + "Gabon", + "Gambia, The", + "Georgia", + "Germany", + "Ghana", + "Greece", + "Grenada", + "Guatemala", + "Guinea", + "Guinea-Bissau", + "Guyana", + "Haiti", + "Honduras", + "Hungary", + "Iceland", + "India", + "Indonesia", + "Iran", + "Iraq", + "Ireland", + "Israel", + "Italy", + "Jamaica", + "Japan", + "Jordan", + "Kazakhstan", + "Kenya", + "Kiribati", + "Korea, North", + "Korea, South", + "Kuwait", + "Kyrgyzstan", + "Laos", + "Latvia", + "Lebanon", + "Lesotho", + "Liberia", + "Libya", + "Liechtenstein", + "Lithuania", + "Luxembourg", + "Macedonia, North", + "Madagascar", + "Malawi", + "Malaysia", + "Maldives", + "Mali", + "Malta", + "Marshall Islands", + "Mauritania", + "Mauritius", + "Mexico", + "Micronesia", + "Moldova", + "Monaco", + "Mongolia", + "Morocco", + "Mozambique", + "Myanmar", + "Namibia", + "Nauru", + "Nepal", + "Netherlands", + "New Zealand", + "Nicaragua", + "Niger", + "Nigeria", + "Norway", + "Oman", + "Pakistan", + "Palau", + "Panama", + "Papua New Guinea", + "Paraguay", + "Peru", + "Philippines", + "Poland", + "Portugal", + "Qatar", + "Romania", + "Russia", + "Rwanda", + "Saint Kitts and Nevis", + "Saint Lucia", + "Saint Vincent", + "Samoa", + "San Marino", + "Sao Tome and Principe", + "Saudi Arabia", + "Senegal", + "Serbia and Montenegro", + "Seychelles", + "Sierra Leone", + "Singapore", + "Slovakia", + "Slovenia", + "Solomon Islands", + "Somalia", + "South Africa", + "South Sudan", + "Spain", + "Sri Lanka", + "Sudan", + "Suriname", + "Swaziland", + "Sweden", + "Switzerland", + "Syria", + "Taiwan", + "Tajikistan", + "Tanzania", + "Thailand", + "Togo", + "Tonga", + "Trinidad and Tobago", + "Tunisia", + "Turkey", + "Turkmenistan", + "Tuvalu", + "Uganda", + "Ukraine", + "United Arab Emirates", + "United Kingdom", + "Uruguay", + "Uzbekistan", + "Vanuatu", + "Vatican City", + "Venezuela", + "Vietnam", + "Yemen", + "Zambia", + "Zimbabwe" + ].freeze + validates_inclusion_of :experience, in: POSSIBLE_EXPERIENCES validates_inclusion_of :interest, in: POSSIBLE_INTERESTS # validates_inclusion_of :school_id, :in => School.select(:id) diff --git a/app/views/application/_missing_country_notice.html.haml b/app/views/application/_missing_country_notice.html.haml new file mode 100644 index 000000000..c2c4f87b1 --- /dev/null +++ b/app/views/application/_missing_country_notice.html.haml @@ -0,0 +1,10 @@ +.alert#disclaimer + %h1.section-title + %span.emphasized.fa.fa-exclamation-circle + Missing + %span.emphasized Country Information + %p + You have not provided the country you are hacking from. Please + %strong + #{link_to "edit your application", edit_questionnaires_path} + and specify your country. diff --git a/app/views/application/_questionnaire_summary.html.haml b/app/views/application/_questionnaire_summary.html.haml index 8f3ae4b7b..818bd7fe0 100644 --- a/app/views/application/_questionnaire_summary.html.haml +++ b/app/views/application/_questionnaire_summary.html.haml @@ -7,10 +7,10 @@ = Questionnaire::POSSIBLE_EXPERIENCES[@questionnaire.experience] %p %b Portfolio link: - = @questionnaire.portfolio_url? ? link_to(@questionnaire.portfolio_url, @questionnaire.portfolio_url, target: '_blank') : 'Not provided' + = @questionnaire.portfolio_url? ? link_to(@questionnaire.portfolio_url, @questionnaire.portfolio_url, target: '_blank', rel: 'noopener') : 'Not provided' %p %b GitHub/GitLab/Bitbucket link: - = @questionnaire.vcs_url? ? link_to(@questionnaire.vcs_url, @questionnaire.vcs_url, target: '_blank') : 'Not provided' + = @questionnaire.vcs_url? ? link_to(@questionnaire.vcs_url, @questionnaire.vcs_url, target: '_blank', rel: 'noopener') : 'Not provided' %p %b Resume: = @questionnaire.resume.attached? ? link_to("Download »".html_safe, @questionnaire.resume) : 'Not provided' @@ -21,9 +21,10 @@ %p %b Shirt size: = @questionnaire.shirt_size -%p - %b Dietary restrictions - = @questionnaire.dietary_restrictions || "(none)".html_safe +- if !HackathonConfig['digital_hackathon'] + %p + %b Dietary restrictions + = @questionnaire.dietary_restrictions || "(none)".html_safe %p %b Special needs = @questionnaire.special_needs || "(none)".html_safe diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index b19583627..7d6375be4 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -1,8 +1,9 @@ - title 'Register' .form-container.signup %h1.section-title.center - Register for - .emphasized.text-overflow-center= HackathonConfig['name'] + Create an + .emphasized.text-overflow-center + Account - if !HackathonConfig['accepting_questionnaires'] || HackathonConfig['disclaimer_message'].present? #disclaimer diff --git a/app/views/layouts/manage/application.html.haml b/app/views/layouts/manage/application.html.haml index 763ca84a0..eb646c60f 100644 --- a/app/views/layouts/manage/application.html.haml +++ b/app/views/layouts/manage/application.html.haml @@ -18,7 +18,7 @@ .fa.fa-bars.m-3.mx-4.text-white.h-auto / TODO: move acc/signin inside the sidebar - %a.navbar-brand.px-3.mr-0{href: manage_root_path} #{HackathonConfig['name']} Manager + %a.navbar-brand.px-3.mr-0.col-xl-2.col-lg-3{href: manage_root_path} #{HackathonConfig['name']} Manager / %input.form-control.form-control-dark.w-100{"aria-label" => "Search", placeholder: "Search", type: "text"}/ %ul.navbar-nav.ml-auto.px-3 @@ -29,7 +29,7 @@ .container-fluid .row - %nav.col-md-3.d-none.d-md-block.bg-light.sidebar + %nav.col-md-3.d-none.d-md-block.bg-light.sidebar.col-xl-2.col-lg-3 .sidebar-sticky %h6.sidebar-heading.d-flex.justify-content-between.align-items-center.px-3.mt-4.mb-1.text-muted %span @@ -68,6 +68,10 @@ = active_link_to manage_checkins_path, class: "nav-link" do .fa.fa-drivers-license-o.fa-fw.icon-space-r-half = t(:title, scope: 'pages.manage.check-in') + %li.nav-item + = active_link_to manage_events_path, class: "nav-link" do + .fa.fa-calendar.fa-fw.icon-space-r-half + = t(:title, scope: 'pages.manage.events') %li.nav-item = active_link_to manage_stats_path, class: "nav-link" do .fa.fa-table.fa-fw.icon-space-r-half @@ -120,14 +124,14 @@ .nav-item-description = t(:doorkeeper, scope: 'layouts.manage.navigation.descriptors') %li.nav-item - = active_link_to sidekiq_web_path, target: '_blank', class: "nav-link" do + = active_link_to sidekiq_web_path, target: '_blank', rel: "noopener", class: "nav-link" do .fa.fa-tasks.fa-fw.icon-space-r-half = t(:title, scope: 'pages.manage.sidekiq') %span.fa.fa-external-link.icon-space-l-half .nav-item-description = t(:sidekiq, scope: 'layouts.manage.navigation.descriptors') %li.nav-item - = active_link_to blazer_path, target: '_blank', class: "nav-link" do + = active_link_to blazer_path, target: '_blank', rel: "noopener", class: "nav-link" do .fa.fa-terminal.fa-fw.icon-space-r-half = t(:title, scope: 'pages.manage.blazer') %span.fa.fa-external-link.icon-space-l-half @@ -139,7 +143,7 @@ = t(:title, scope: 'pages.manage.data-exports') .nav-item-description = t(:dataexports, scope: 'layouts.manage.navigation.descriptors') - %main.col-md-9.ml-sm-auto.px-4{role: "main"} + %main.col-md-9.ml-sm-auto.px-4.col-xl-10.col-lg-9{role: "main"} = render "layouts/manage/flashes" = yield %div.mb-4.text-center diff --git a/app/views/manage/agreements/index.html.haml b/app/views/manage/agreements/index.html.haml index be0c560ac..f208a571b 100644 --- a/app/views/manage/agreements/index.html.haml +++ b/app/views/manage/agreements/index.html.haml @@ -17,7 +17,7 @@ %tbody - @agreements.each do |agreement| %tr - %td + %td.narrow-icon = link_to ''.html_safe, edit_manage_agreement_path(agreement) %td = link_to ''.html_safe, manage_agreement_path(agreement), method: :delete, data: { confirm: "Are you sure? The agreement will be permanently deleted. This action is irreversible." } diff --git a/app/views/manage/dashboard/index.html.haml b/app/views/manage/dashboard/index.html.haml index c0642f5e3..615ca596e 100644 --- a/app/views/manage/dashboard/index.html.haml +++ b/app/views/manage/dashboard/index.html.haml @@ -11,6 +11,8 @@ = render "layouts/manage/page_title", title: t(:title, scope: 'pages.manage.dashboard') +%button.btn.btn-secondary.w-100.map-button Show Map + .row .col #map diff --git a/app/views/manage/data_exports/_form.html.haml b/app/views/manage/data_exports/_form.html.haml index 015ad70d3..6d108063f 100644 --- a/app/views/manage/data_exports/_form.html.haml +++ b/app/views/manage/data_exports/_form.html.haml @@ -1,11 +1,9 @@ .form-container = bs_horizontal_simple_form_for @data_export, url: url_for(action: @data_export.new_record? ? "create" : "update", controller: "data_exports") do |f| = f.error_notification - - .form-inputs - = f.input :export_type, as: :select, collection: DataExport::POSSIBLE_TYPES.map { |x| [x.titleize, x] }, include_blank: false - - .form-actions.mb-3.mt-3 - = f.button :submit, class: 'btn-primary' + .form-inputs + = f.input :export_type, as: :select, collection: DataExport::POSSIBLE_TYPES.map { |x| [x.titleize, x] }, include_blank: false + .form-actions.mb-3.mt-3 + = f.button :submit, class: 'btn-primary' .mb-4 diff --git a/app/views/manage/events/_form.html.haml b/app/views/manage/events/_form.html.haml new file mode 100644 index 000000000..10c8dd6bb --- /dev/null +++ b/app/views/manage/events/_form.html.haml @@ -0,0 +1,12 @@ += bs_horizontal_simple_form_for @event, url: url_for(action: @event.new_record? ? "create" : "update", controller: "events") do |f| + = f.error_notification + .form-inputs + = f.input :title + = f.input :description + = f.input :location + = f.input :category + = f.input :start + = f.input :finish, include_blank: true + .center + //TODO figure out why you need to add save and it doesn't work automatically like other forms + = f.button :submit, 'Save', value: ( @event.new_record? ? 'Create' : 'Save' ), class: 'btn-primary' diff --git a/app/views/manage/events/index.html.haml b/app/views/manage/events/index.html.haml new file mode 100644 index 000000000..ec20c6204 --- /dev/null +++ b/app/views/manage/events/index.html.haml @@ -0,0 +1,4 @@ += render "layouts/manage/page_title", title: t(:title, scope: 'pages.manage.events') do + = link_to "Add Event", new_manage_event_path, class: "btn btn-sm btn-outline-secondary" + +.calendar-list#calendar diff --git a/app/views/manage/events/new.html.haml b/app/views/manage/events/new.html.haml new file mode 100644 index 000000000..c195ba28c --- /dev/null +++ b/app/views/manage/events/new.html.haml @@ -0,0 +1,4 @@ += render "layouts/manage/page_title", title: "New Event" + +.form-container + = render "form" diff --git a/app/views/manage/events/show.html.haml b/app/views/manage/events/show.html.haml new file mode 100644 index 000000000..ece45ff02 --- /dev/null +++ b/app/views/manage/events/show.html.haml @@ -0,0 +1,6 @@ += render "layouts/manage/page_title", title: "Edit Event", subtitle: @event.title do + .btn-group + = link_to 'Cancel', manage_events_path, class: 'btn btn-sm btn-outline-secondary' + = link_to 'Delete', manage_event_path(@event), method: :delete, data: { confirm: 'Are you sure? This action is irreversible.' }, class: 'btn btn-sm btn-outline-secondary' + += render "form" diff --git a/app/views/manage/messages/_templating.haml b/app/views/manage/messages/_templating.haml index 6a3b1c0ad..0ba432173 100644 --- a/app/views/manage/messages/_templating.haml +++ b/app/views/manage/messages/_templating.haml @@ -2,7 +2,7 @@ %p Message bodies can make use of template variables to help personalize and streamline emails. - Templating is powered by mustache. + Templating is powered by mustache. %table.table.table-striped %thead diff --git a/app/views/manage/messages/template.haml b/app/views/manage/messages/template.haml index dd7de592c..517c48943 100644 --- a/app/views/manage/messages/template.haml +++ b/app/views/manage/messages/template.haml @@ -22,7 +22,7 @@ .form-inputs %h5.mb-3 Customize template %p.text-secondary Must save to update preview. CSS will be converted to inline styles when messages are sent. - %p.text-secondary Be sure to test with as many email providers as possible! Litmus PutsMail is one great resource. + %p.text-secondary Be sure to test with as many email providers as possible! Litmus PutsMail is one great resource. = f.input :html, input_html: { 'data-code-mirror-textarea' => '1' }, label: false, wrapper: :bootstrap_inline_form .form-actions.mt-3.mb-3 diff --git a/app/views/manage/questionnaires/_form.html.haml b/app/views/manage/questionnaires/_form.html.haml index 34e2bfed3..498e9bbee 100644 --- a/app/views/manage/questionnaires/_form.html.haml +++ b/app/views/manage/questionnaires/_form.html.haml @@ -22,6 +22,7 @@ = f.input :level_of_study, input_html: { "data-validate" => "presence" } = f.input :major, input_html: { "data-validate" => "presence" } = f.input :gender, input_html: { "data-validate" => "presence" } + = f.input :country, as: :select, collection: Questionnaire::POSSIBLE_COUNTRIES, include_blank: "(select one...)", input_html: { "data-validate" => "presence" } - if !HackathonConfig['digital_hackathon'] .card.mb-4 diff --git a/app/views/manage/questionnaires/_overview.html.haml b/app/views/manage/questionnaires/_overview.html.haml index ffdfecdd9..b6ebc3a22 100644 --- a/app/views/manage/questionnaires/_overview.html.haml +++ b/app/views/manage/questionnaires/_overview.html.haml @@ -23,6 +23,8 @@ = @questionnaire.age_at_time_of_event / 1.year %dt.col-md-4 Gender %dd.col-md-8= @questionnaire.gender + %dt.col-md-4 Country + %dd.col-md-8= @questionnaire.country = render 'checkin_compliance_card' @@ -33,13 +35,14 @@ .row %dt.col-md-4 Shirt size %dd.col-md-8= @questionnaire.shirt_size - %dt.col-md-4 Dietary restrictions - %dd.col-md-8 - - if @questionnaire.dietary_restrictions.present? - %span.fa.fa-exclamation-triangle.text-warning.icon-space-r-half - = @questionnaire.dietary_restrictions - - else - %span.text-muted (none) + - if !HackathonConfig['digital_hackathon'] + %dt.col-md-4 Dietary restrictions + %dd.col-md-8 + - if @questionnaire.dietary_restrictions.present? + %span.fa.fa-exclamation-triangle.text-warning.icon-space-r-half + = @questionnaire.dietary_restrictions + - else + %span.text-muted (none) %dt.col-md-4 Special needs %dd.col-md-8 - if @questionnaire.special_needs.present? @@ -86,10 +89,10 @@ = Questionnaire::POSSIBLE_EXPERIENCES[@questionnaire.experience] %dt.col-md-4 Portfolio %dd.col-md-8 - = @questionnaire.portfolio_url? ? link_to(@questionnaire.portfolio_url, @questionnaire.portfolio_url, target: '_blank') : not_provided + = @questionnaire.portfolio_url? ? link_to(@questionnaire.portfolio_url, @questionnaire.portfolio_url, target: '_blank', rel: 'noopener') : not_provided %dt.col-md-4 GitHub/GitLab/Bitbucket %dd.col-md-8 - = @questionnaire.vcs_url? ? link_to(@questionnaire.vcs_url, @questionnaire.vcs_url, target: '_blank') : not_provided + = @questionnaire.vcs_url? ? link_to(@questionnaire.vcs_url, @questionnaire.vcs_url, target: '_blank', rel: 'noopener') : not_provided %dt.col-md-4 Resume %dd.col-md-8 = @questionnaire.resume.attached? ? link_to("Download »".html_safe, @questionnaire.resume) : not_provided diff --git a/app/views/manage/schools/show.html.haml b/app/views/manage/schools/show.html.haml index 9a08d1bc5..41bcf4849 100644 --- a/app/views/manage/schools/show.html.haml +++ b/app/views/manage/schools/show.html.haml @@ -25,7 +25,7 @@ = @school.name %br %small - = link_to google_maps_link(@school.name), target: '_blank' do + = link_to google_maps_link(@school.name), target: '_blank', rel: 'noopener' do Search in Google Maps %span.fa.fa-external-link.icon-space-l-half %dt.col-md-4 Address @@ -37,7 +37,7 @@ %br %small - link = google_maps_link(@school.address, @school.city, @school.state) - = link_to link, target: '_blank' do + = link_to link, target: '_blank', rel: 'noopener' do Search in Google Maps %span.fa.fa-external-link.icon-space-l-half %dt.col-md-4 Home school diff --git a/app/views/manage/stats/index.html.haml b/app/views/manage/stats/index.html.haml index 7451827a2..22ae4ab48 100644 --- a/app/views/manage/stats/index.html.haml +++ b/app/views/manage/stats/index.html.haml @@ -2,79 +2,77 @@ .row .col - %h5.dashboard-container-title Dietary Restrictions or Special Needs + %h5.dashboard-container-title= t(:dietary_restrictions_special_needs, scope: 'pages.manage.stats') %table.datatable.stats-dietary.table.table-striped.table-hover{ "data-source" => dietary_restrictions_special_needs_datatable_manage_stats_path(format: :json) } %thead %tr - %th ID - %th First Name - %th Last Name - %th Email - %th Phone - %th Questionnaire - %th Checked In - %th Dietary Restrictions - %th Special Needs + %th= t(:id, scope: 'pages.manage.stats') + %th= t(:first_name, scope: 'pages.manage.stats') + %th= t(:last_name, scope: 'pages.manage.stats') + %th= t(:email, scope: 'pages.manage.stats') + %th= t(:phone, scope: 'pages.manage.stats') + %th= t(:questionnaire, scope: 'pages.manage.stats') + %th= t(:checked_in, scope: 'pages.manage.stats') + %th= t(:dietary_restrictions, scope: 'pages.manage.stats') + %th= t(:special_needs, scope: 'pages.manage.stats') %tbody - if !HackathonConfig['digital_hackathon'] .row .col - %h5.dashboard-container-title Attendees Not Traveling From Their School + %h5.dashboard-container-title= t(:attendees_not_traveling_from_their_school, scope: 'pages.manage.stats') %table.datatable.stats-notschooltravel.table.table-striped.table-hover{ "data-source" => alt_travel_datatable_manage_stats_path(format: :json) } %thead %tr - %th ID - %th First Name - %th Last Name - %th Email - %th Phone - %th Questionnaire - %th Traveling From - %th Questionnaire Status + %th= t(:id, scope: 'pages.manage.stats') + %th= t(:first_name, scope: 'pages.manage.stats') + %th= t(:last_name, scope: 'pages.manage.stats') + %th= t(:email, scope: 'pages.manage.stats') + %th= t(:phone, scope: 'pages.manage.stats') + %th= t(:questionnaire, scope: 'pages.manage.stats') + %th= t(:traveling_from, scope: 'pages.manage.stats') + %th= t(:questionnaire_status, scope: 'pages.manage.stats') %tbody .row .col - %h5.dashboard-container-title Attendee Info for Sponsors + %h5.dashboard-container-title= t(:attendee_info_for_sponsors, scope: 'pages.manage.stats') %table.datatable.stats-attendeeinfo.table.table-striped.table-hover{ "data-source" => attendee_sponsor_info_datatable_manage_stats_path(format: :json) } %thead %tr - %th ID - %th First name - %th Last name - %th Email - %th School - %th Open Source Link - %th Portfolio Link + %th= t(:id, scope: 'pages.manage.stats') + %th= t(:first_name, scope: 'pages.manage.stats') + %th= t(:last_name, scope: 'pages.manage.stats') + %th= t(:email, scope: 'pages.manage.stats') + %th= t(:school, scope: 'pages.manage.stats') + %th= t(:open_source_link, scope: 'pages.manage.stats') + %th= t(:portfolio_link, scope: 'pages.manage.stats') %tbody .row .col - %h5.dashboard-container-title MLH Info (applied) - %table.datatable.stats-mlhinfo-applied.table.table-striped.table-hover{ "data-source" => mlh_applied_datatable_manage_stats_path(format: :json) } + %h5.dashboard-container-title= t(:applied_attendees, scope: 'pages.manage.stats') + %table.datatable.stats-info-applied.table.table-striped.table-hover{ "data-source" => applied_datatable_manage_stats_path(format: :json) } %thead %tr - %th ID - %th First name - %th Last name - %th Email - %th Phone - %th School Name + %th= t(:id, scope: 'pages.manage.stats') + %th= t(:first_name, scope: 'pages.manage.stats') + %th= t(:last_name, scope: 'pages.manage.stats') + %th= t(:email, scope: 'pages.manage.stats') + %th= t(:phone, scope: 'pages.manage.stats') + %th= t(:school, scope: 'pages.manage.stats') %tbody .row .col - %h5.dashboard-container-title MLH Info (checked in) - %table.datatable.stats-mlhinfo-checkedin.table.table-striped.table-hover{ "data-source" => mlh_checked_in_datatable_manage_stats_path(format: :json) } + %h5.dashboard-container-title= t(:checked_in_attendees, scope: 'pages.manage.stats') + %table.datatable.stats-info-checkedin.table.table-striped.table-hover{ "data-source" => checked_in_datatable_manage_stats_path(format: :json) } %thead %tr - %th ID - %th First name - %th Last name - %th Email - %th Phone - %th School Name + %th= t(:id, scope: 'pages.manage.stats') + %th= t(:first_name, scope: 'pages.manage.stats') + %th= t(:last_name, scope: 'pages.manage.stats') + %th= t(:email, scope: 'pages.manage.stats') + %th= t(:phone, scope: 'pages.manage.stats') + %th= t(:school, scope: 'pages.manage.stats') %tbody - -.mb-4 diff --git a/app/views/manage/users/_form.html.haml b/app/views/manage/users/_form.html.haml index ca1af575d..6f16a467c 100644 --- a/app/views/manage/users/_form.html.haml +++ b/app/views/manage/users/_form.html.haml @@ -6,6 +6,8 @@ = f.error_notification .form-inputs + = f.input :first_name, required: true + = f.input :last_name, required: true = f.input :email, input_html: { "data-validate" => "presence" }, required: true = f.input :role, collection: User.roles.to_a.collect{|c| [c[0].titleize, c[0]]}, include_blank: false = f.input :is_active, collection: [[t(:active, scope: "pages.manage.users.edit.form"), true], [t(:inactive, scope: "pages.manage.users.edit.form"), false]], as: :radio_buttons diff --git a/app/views/manage/users/edit.html.haml b/app/views/manage/users/edit.html.haml index f2f911fa0..7a7334b68 100644 --- a/app/views/manage/users/edit.html.haml +++ b/app/views/manage/users/edit.html.haml @@ -1,6 +1,8 @@ -= render "layouts/manage/page_title", title: t(:title, scope: "pages.manage.users.edit", user_email: @user.email), subtitle: @user.email do += render "layouts/manage/page_title", title: @user.full_name, subtitle: t(:subtitle, scope: 'pages.manage.users.edit') do + .btn-group = link_to t(:cancel, scope: "pages.manage.users.edit"), manage_user_path(@user), class: 'btn btn-sm btn-outline-secondary' + = link_to t(:reset_password, scope: "pages.manage.users.edit"), reset_password_manage_user_path(@user), method: :patch, data: { confirm: t(:confirm_reset_password, scope: "pages.manage.users.edit", full_name: @user.full_name, first_name: @user.first_name)}, class: 'btn btn-sm btn-outline-secondary' = link_to t(:delete, scope: "pages.manage.users.edit"), manage_user_path(@user), method: :delete, data: { confirm: "Are you sure? #{@user.email} will be permanently deleted. This action is irreversible." }, class: 'btn btn-sm btn-outline-secondary' = render 'form' diff --git a/app/views/manage/users/show.html.haml b/app/views/manage/users/show.html.haml index 7b3387e32..1ee34f32d 100644 --- a/app/views/manage/users/show.html.haml +++ b/app/views/manage/users/show.html.haml @@ -1,4 +1,5 @@ -= render "layouts/manage/page_title", title: t(:title, scope: "pages.manage.users.show", user_email: @user.email) do += render "layouts/manage/page_title", title: @user.full_name, subtitle: t(:subtitle, scope: 'pages.manage.users.show') do + .btn-group = link_to t(:edit, scope: "pages.manage.users.show"), edit_manage_user_path(@user), class: 'btn btn-sm btn-outline-secondary' = link_to t(:delete, scope: "pages.manage.users.show"), manage_user_path(@user), method: :delete, data: { confirm: "Are you sure? #{@user.email} along with their questionnaire will be permanently deleted. This action is irreversible." }, class: 'btn btn-sm btn-outline-secondary' @@ -8,6 +9,12 @@ .card.mb-3 .card-header= t(:user_information, scope: "pages.manage.users.show") .card-body + .row + %dt.col-md-5= t(:first_name, scope: "pages.manage.users.show") + %dd.col-md-7= @user.first_name + .row + %dt.col-md-5= t(:last_name, scope: "pages.manage.users.show") + %dd.col-md-7= @user.last_name .row %dt.col-md-5= t(:email_address, scope: "pages.manage.users.show") %dd.col-md-7= @user.email diff --git a/app/views/questionnaires/_form.html.haml b/app/views/questionnaires/_form.html.haml index ba8a35948..83b270151 100644 --- a/app/views/questionnaires/_form.html.haml +++ b/app/views/questionnaires/_form.html.haml @@ -30,6 +30,7 @@ = f.input :graduation_year, as: :select, collection: Questionnaire::POSSIBLE_GRAD_YEARS, include_blank: "(select one...)", label: "Graduation year", input_html: { "data-validate" => "presence" }, wrapper_html: { class: 'input--half' } = f.input :race_ethnicity, as: :select, collection: Questionnaire::POSSIBLE_RACE_ETHNICITIES, include_blank: "(select one...)", label: "Race/Ethnicity", input_html: { "data-validate" => "presence" }, wrapper_html: { class: 'input--half' } + = f.input :country, as: :select, collection: Questionnaire::POSSIBLE_COUNTRIES, include_blank: "(select one...)", input_html: { "data-validate" => "presence" } = f.input :portfolio_url, label: "Portfolio link", placeholder: "http://mywebsite.com" = f.input :vcs_url, label: "GitHub/GitLab/Bitbucket link", placeholder: "https://github.com/coderit" @@ -44,7 +45,7 @@ = f.input :shirt_size, as: :select, collection: Questionnaire::POSSIBLE_SHIRT_SIZES, include_blank: "(select one...)", input_html: { "data-validate" => "presence" } - if !HackathonConfig['digital_hackathon'] - = f.input :dietary_restrictions, as: :text, label: "Health restrictions", wrapper_html: { class: 'input--half' }, maxlength: Questionnaire::DIETARY_SPECIAL_NEEDS_MAX_LENGTH + = f.input :dietary_restrictions, as: :text, label: "Dietary restrictions", wrapper_html: { class: 'input--half' }, maxlength: Questionnaire::DIETARY_SPECIAL_NEEDS_MAX_LENGTH = f.input :special_needs, as: :text, label: "Special needs", wrapper_html: { class: 'input--half' }, maxlength: Questionnaire::DIETARY_SPECIAL_NEEDS_MAX_LENGTH - if @agreements.any? @@ -52,8 +53,7 @@ %strong Agreements %p Please review the agreements and click the corresponding checkbox next to each agreement to agree. .form-inputs - .agreement_input - = f.association :agreements, as: :check_boxes, label_method: :formatted_agreement, value_method: :id, label: "", wrapper_html: { style: 'display: block' }, input_html: { "data-validate" => "presence" } + = f.association :agreements, as: :check_boxes, label_method: :formatted_agreement, value_method: :id, label: "", wrapper_html: { style: 'display: block' }, input_html: { "data-validate" => "presence", class: "agreement_input"} .right %button.button{ type: "button", "data-wizard" => "previous" } Previous diff --git a/app/views/questionnaires/show.html.haml b/app/views/questionnaires/show.html.haml index fe10da604..7dc357946 100644 --- a/app/views/questionnaires/show.html.haml +++ b/app/views/questionnaires/show.html.haml @@ -2,6 +2,8 @@ .form-container - if @questionnaire.unaccepted_agreements.any? = render partial: 'unaccepted_agreements_notice' + - if @questionnaire.country.blank? + = render partial: 'missing_country_notice' .form-container #disclaimer %h1.section-title diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb new file mode 100644 index 000000000..054f8b2b3 --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,6 @@ +Rails.application.config.middleware.insert_before 0, Rack::Cors do + allow do + origins '*' + resource '*/events.json', headers: :any, methods: [:get] # Workaround for now + end +end diff --git a/config/locales/en.yml b/config/locales/en.yml index b806ca6b6..ed11daa8b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -47,7 +47,11 @@ en: If many people have already RSVP'd, consider sending a message out to this bus list asking for interest as well. notes: Notes are shared with applicants. Supports Markdown and HTML. user: - role: Limited access prevents the admin from adding, modifying, or deleting any records; modifications through the check-in process are allowed. Event tracking limits to only event tracking. + role: | + Users can only access and edit their own information
- Yes, I will Attend »
- No, I Can't Attend »
+ Yes, I will Attend »
+ No, I Can't Attend »
- Link not working? Go to {{rsvp_url}}
+ Link not working? Go to {{rsvp_url}}
- Yes, I will Attend »
- No, I Can't Attend »
+ Yes, I will Attend »
+ No, I Can't Attend »
- Link not working? Go to {{rsvp_url}}
+ Link not working? Go to {{rsvp_url}}