Skip to content

Commit

Permalink
Merge pull request #295 from cs169/187216522-international-schools
Browse files Browse the repository at this point in the history
187216522 international schools
  • Loading branch information
cycomachead authored May 10, 2024
2 parents 9d0786c + 163e2a9 commit 5b2c3fe
Show file tree
Hide file tree
Showing 31 changed files with 448 additions and 189 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ jobs:
run: |
export GIT_BRANCH="${GITHUB_REF/refs\/heads\//}"
$CCTR sum-coverage coverage/codeclimate.*.json
$CCTR upload-coverage --id "$CC_TEST_REPORTER_ID"
$CCTR upload-coverage --id "${{ secrets.CC_TEST_REPORTER_ID }}"
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ gem "activerecord-import", require: false

gem "httparty", "~> 0.21.0"


gem "country_select", "~> 8.0"

group :development do
gem "annotate"

Expand Down
6 changes: 6 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ GEM
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.2.3)
countries (5.7.2)
unaccent (~> 0.3)
country_select (8.0.3)
countries (~> 5.0)
crass (1.0.6)
cucumber (7.1.0)
builder (~> 3.2, >= 3.2.4)
Expand Down Expand Up @@ -528,6 +532,7 @@ GEM
concurrent-ruby (~> 1.0)
tzinfo-data (1.2021.5)
tzinfo (>= 1.0.0)
unaccent (0.4.0)
unicode-display_width (2.4.2)
version_gem (1.1.3)
virtus (2.0.0)
Expand Down Expand Up @@ -563,6 +568,7 @@ DEPENDENCIES
axe-core-cucumber
axe-core-rspec
bootsnap (>= 1.4.4)
country_select (~> 8.0)
cucumber-rails
database_cleaner
debug
Expand Down
17 changes: 17 additions & 0 deletions app/controllers/concerns/school_params.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module SchoolParams
private
def unique_school_params
{
name: school_params[:name],
country: school_params[:country],
city: school_params[:city],
state: school_params[:state]
}
end

def school_params
params.require(:school).permit(:name, :country, :city, :state, :website, :grade_level, :school_type, :country, { tags: [] }, :nces_id)
end
end
4 changes: 2 additions & 2 deletions app/controllers/email_templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def update
flash[:success] = "Updated #{@email_template.title} template successfully."
redirect_to email_templates_path
else
flash.now[:alert] = "Failed to save #{@email_template.title} template: #{@email_template.errors.full_messages.join(", ")}"
flash.now[:alert] = "An error occurred: #{@email_template.errors.full_messages.join(", ")}"
render "edit"
end
end
Expand All @@ -36,7 +36,7 @@ def create
flash[:success] = "Created #{@email_template.title} successfully."
redirect_to email_templates_path
else
flash.now[:alert] = "Failed to submit information: #{@email_template.errors.full_messages.join(", ")}"
flash.now[:alert] = "An error occurred: #{@email_template.errors.full_messages.join(", ")}"
render "new"
end
end
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def create
flash[:success] = "Created #{@page.title} page successfully."
redirect_to action: "show", url_slug: @page.url_slug
else
flash.now[:alert] = "An error occurred! #{@page.errors.full_messages}"
flash.now[:alert] = "An error occurred: #{@page.errors.full_messages.join(", ")}"
render "edit"
end
end
Expand Down Expand Up @@ -58,7 +58,7 @@ def update
flash[:success] = "Updated #{@page.title} page successfully."
redirect_to pages_path
else
flash.now[:alert] = "An error occurred! #{@page.errors.full_messages.to_sentence}"
flash.now[:alert] = "An error occurred: #{@page.errors.full_messages.join(', ')}"
render "edit"
end
end
Expand Down
16 changes: 7 additions & 9 deletions app/controllers/schools_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

class SchoolsController < ApplicationController
include SchoolParams
before_action :require_admin

def index
Expand All @@ -12,11 +13,11 @@ def show
end

def search
School.all.collect { |school| ["#{school.name}, #{school.city}, #{school.state}", school.name] }
School.search_list
end

def create
@school = School.find_by(name: school_params[:name], city: school_params[:city], state: school_params[:state])
@school = School.find_by(**unique_school_params)
if @school
@school.assign_attributes(school_params)
else
Expand All @@ -27,7 +28,7 @@ def create
flash[:success] = "Created #{@school.name} successfully."
redirect_to schools_path
else
flash[:alert] = "Failed to submit information :("
flash[:alert] = "An error occurred: #{@school.errors.full_messages.join(', ')}"
render "new"
end
end
Expand All @@ -45,10 +46,11 @@ def update
@school = School.find(params[:id])
@school.assign_attributes(school_params)
if @school.save
flash[:success] = "Update #{@school.name} successfully."
flash[:success] = "Updated #{@school.name} successfully."
redirect_to school_path(@school)
else
render "edit", alert: "Failed to submit information :("
flash[:alert] = "An error occurred: #{@school.errors.full_messages.join(', ')}"
render "edit"
end
end

Expand All @@ -63,10 +65,6 @@ def destroy
end

private
def school_params
params.require(:school).permit(:name, :city, :state, :website, :grade_level, :school_type, { tags: [] }, :nces_id)
end

def load_ordered_schools
@ordered_schools ||= School.all.order(:name)
end
Expand Down
22 changes: 11 additions & 11 deletions app/controllers/teachers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require "activerecord-import"

class TeachersController < ApplicationController
include SchoolParams
include CsvProcess

before_action :load_pages, only: [:new, :create, :edit, :update]
Expand Down Expand Up @@ -63,9 +64,10 @@ def create

load_school
if @school.new_record?
return unless params[:school]
@school = School.new(school_params)
unless @school.save
flash[:alert] = "An error occurred! #{@school.errors.full_messages}"
flash[:alert] = "An error occurred: #{@school.errors.full_messages.join(', ')}"
render "new" && return
end
end
Expand All @@ -81,7 +83,7 @@ def create
TeacherMailer.teacher_form_submission(@teacher).deliver_now
redirect_to root_path
else
redirect_to new_teacher_path, alert: "An error occurred while trying to save. #{@teacher.errors.full_messages}"
redirect_to new_teacher_path, alert: "An error occurred: #{@teacher.errors.full_messages.join(', ')}"
end
end

Expand All @@ -100,7 +102,10 @@ def update
@teacher.school = @school
else
@school.update(school_params) if school_params
@school.save!
unless @school.save
flash[:alert] = "An error occurred: #{@school.errors.full_messages.join(', ')}"
render "edit" && return
end
@teacher.school = @school
end
send_email_if_application_status_changed_and_email_resend_enabled
Expand All @@ -114,15 +119,15 @@ def update
end
if !@teacher.save
redirect_to edit_teacher_path(current_user.id),
alert: "Failed to update data. #{@teacher.errors.full_messages.to_sentence}"
alert: "An error occurred: #{@teacher.errors.full_messages.join(', ')}"
return
end
if !@teacher.validated? && !current_user.admin?
TeacherMailer.form_submission(@teacher).deliver_now
TeacherMailer.teacher_form_submission(@teacher).deliver_now
end
if is_admin?
redirect_to teachers_path, notice: "Saved #{@teacher.full_name}"
redirect_to edit_teacher_path(current_user.id), notice: "Saved #{@teacher.full_name}"
return
else
@teacher.try_append_ip(request.remote_ip)
Expand Down Expand Up @@ -202,7 +207,7 @@ def load_school
if teacher_params[:school_id].present?
@school ||= School.find(teacher_params[:school_id])
end
@school ||= School.find_or_create_by(name: school_params[:name], city: school_params[:city], state: school_params[:state])
@school ||= School.find_or_create_by(**unique_school_params)
end

def teacher_params
Expand All @@ -215,11 +220,6 @@ def teacher_params
params.require(:teacher).permit(*teacher_attributes)
end

def school_params
return unless params[:school]
params.require(:school).permit(:name, :city, :state, :website, :grade_level, :school_type)
end

def omniauth_data
@omniauth_data ||= session[:auth_data]&.slice("first_name", "last_name", "email")
end
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/packs/datatables.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ $(function() {
$.fn.dataTable.ext.search.push((_, searchData) => {
let enabled = $('input:checkbox[name="statusFilter"]:checked').map((_i, el) => el.value).get();
// Include all rows when no checkboxes are selected.
return enabled.length === 0 || enabled.includes(searchData[6]);
return enabled.length === 0 || enabled.includes(searchData[7]);
});

let $tables = $('.js-dataTable').DataTable({
Expand Down
4 changes: 2 additions & 2 deletions app/models/email_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class EmailTemplate < ApplicationRecord
validates :title,
inclusion: TeacherMailer.instance_methods(false).map { |method| method.to_s.titlecase },
if: -> { self.required? }
validates :body, presence: { message: "cannot be blank" }
validates :to, presence: { message: "cannot be blank" }
validates :body, presence: true
validates :to, presence: true

before_destroy :prevent_deleting_required_emails

Expand Down
27 changes: 20 additions & 7 deletions app/models/school.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#
# id :integer not null, primary key
# city :string
# country :string
# grade_level :integer
# lat :float
# lng :float
Expand All @@ -25,10 +26,11 @@
#

class School < ApplicationRecord
VALID_STATES = [ "AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VI", "VA", "WA", "WV", "WI", "WY", "International"].freeze

validates :state, inclusion: { in: VALID_STATES }
validates :name, :city, :state, :website, presence: true
VALID_STATES = ISO3166::Country["US"].subdivisions.keys.freeze
validates :name, :city, :website, :country, presence: true
validates :country, inclusion: { in: ISO3166::Country.all.map(&:alpha2), message: "%{value} is not a valid country" }
validates :state, presence: true, if: -> { country == "US" }
validates :state, inclusion: { in: VALID_STATES }, if: -> { country == "US" }
validates_format_of :website, with: /.+\..+/, on: :create

before_save :update_gps_data, if: -> { lat.nil? || lng.nil? }
Expand Down Expand Up @@ -58,7 +60,8 @@ def website
end

def location
"#{city}, #{state}"
country_text = country == "US" ? "" : ", #{country}"
"#{city}, #{state}#{country_text}"
end

# TODO: Consider renaming this.
Expand All @@ -75,11 +78,11 @@ def display_grade_level
end

def selectize_options
[name_location, to_json(only: [:id, :name, :city, :state, :website]) ]
[name_location, to_json(only: [:id, :name, :city, :state, :country, :website]) ]
end

def name_location
"#{name} (#{city}, #{state})"
"#{name} (#{city}, #{state}, #{country})"
end

def update_gps_data
Expand All @@ -98,6 +101,16 @@ def maps_marker_data
}
end

def format_school(data)
name, city, state, country = data
country_str = country == "US" ? "" : ", #{country}"
"#{name} (#{city}, #{state}#{country_str})"
end

def self.search_list
School.pluck(:name, :city, :state, :country).map(&:format_school)
end

def self.grade_level_options
School.grade_levels.map { |key, _val| [key.to_s.titlecase, key] }
end
Expand Down
59 changes: 51 additions & 8 deletions app/views/schools/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
<div class="form-group h3">Create a new School</div>
<div class='form-group row'>
<div class='col-6'>
<div class='col'>
<%= f.label :name, "School Name", class: "label-required" %>
<%= f.text_field :name, placeholder: 'UC Berkeley', class: 'form-control',
required: false, id: 'school_name' %>
</div>

</div>
<div class='form-group row'>
<div class='col-4'>
<%= f.label :city, class: "label-required", for: "school_city" %>
<%= f.text_field :city, placeholder: 'Berkeley', class: 'form-control',
required: false, id: 'school_city' %>
</div>

<div class='col-2'>
<div class='col-4' id="state_select_container">
<%= f.label :state, class: "label-required", for: "school_state" %>
<%= f.select(
:state,
School::VALID_STATES,
{ include_blank: "State" },
{ class: 'form-control', required: false, id: 'school_state'}
<%= f.select :state, School::VALID_STATES, { include_blank: "Select a state" }, { id: "state_select", class: 'form-control' } %>
</div>

<div class='col-4' id="state_textfield_container">
<%= f.label :state, for: "school_state" %>
<%= f.text_field :state, placeholder: "Name of State", class: 'form-control', id: "state_textfield" %>
</div>

<div class='col-4'>
<%= f.label :country, "Country", class: "label-required", for: "school_country" %>
<%= f.country_select(
:country,
{ priority_countries: ['United States'], include_blank: "Select a country" },
{ class: 'form-control', required: false, id: 'school_country', format: :with_full_country_name, selected: 'United States'}
) %>
</div>

</div>

<div class="form-group">
Expand Down Expand Up @@ -88,3 +99,35 @@
class: "form-control", title: "Please enter a valid NCES ID.", id: "school_nces_id" %>
</div>
<%- end %>

<script>
$(document).ready(function() {
const countrySelected = $('#school_country');
const stateSelectContainer = $('#state_select_container');
const stateTextfieldContainer = $('#state_textfield_container');
const stateSelect = $('#state_select');
const stateTextfield = $('#state_textfield');

function handleCountryChange() {
if (countrySelected.val() === 'US') {
stateSelectContainer.show();
stateSelect.attr('required', '') //make state select required
stateTextfieldContainer.hide();

stateTextfield.removeAttr('name');
stateSelect.attr('name', 'school[state]');

} else {
stateTextfieldContainer.show();
stateSelect.removeAttr('required')
stateSelectContainer.hide();


stateSelect.removeAttr('name');
stateTextfield.attr('name', 'school[state]');
}
}
countrySelected.change(handleCountryChange);
handleCountryChange();
});
</script>
Loading

0 comments on commit 5b2c3fe

Please sign in to comment.