Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/components/chapter_picker_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
list: datalist_id,
placeholder: @placeholder,
class: 'form-control',
required: @required,
autocomplete: 'off' %>

<%= tag.datalist id: datalist_id do %>
Expand Down
3 changes: 2 additions & 1 deletion app/components/chapter_picker_component.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# frozen_string_literal: true

class ChapterPickerComponent < ViewComponent::Base
def initialize(name:, chapters:, selected: nil, placeholder: 'Select a chapter')
def initialize(name:, chapters:, selected: nil, placeholder: 'Select a chapter', required: false)
super()
@name = name
@chapters = chapters
@selected = selected
@placeholder = placeholder
@required = required
end

def datalist_id
Expand Down
6 changes: 3 additions & 3 deletions app/models/workshop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ class Workshop < ApplicationRecord
validates :student_spaces, numericality: { greater_than: 0 }, if: :virtual?
validates :coach_spaces, numericality: { greater_than: 0 }, if: :virtual?

before_validation :set_date_and_time, :set_end_date_and_time, if: proc { |model| model.chapter_id.present? }
before_validation :set_opens_at
before_validation :set_closes_at
before_validation :set_date_and_time, :set_end_date_and_time,
:set_opens_at, :set_closes_at,
if: proc { |model| model.chapter_id.present? }
validate :rsvp_date_time_fields_must_be_paired
validate :rsvp_close_before_workshop_start

Expand Down
16 changes: 8 additions & 8 deletions app/views/admin/workshops/_shared_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
= f.hidden_field :chapter_id
- else
.col-12
= render(ChapterPickerComponent.new(name: 'workshop[chapter_id]', chapters: Chapter.available_to_user(current_user), placeholder: 'Select a chapter'))
= render(ChapterPickerComponent.new(name: 'workshop[chapter_id]', chapters: Chapter.available_to_user(current_user), placeholder: 'Select a chapter', required: true))
.col-12
= f.input :local_date, label: 'Date', required: true, input_html: { value: @workshop.date_and_time.try(:strftime, '%Y-%m-%d'), type: :date }
= f.input :local_date, label: 'Date', required: true, input_html: { value: @workshop.local_date.presence || @workshop.date_and_time.try(:strftime, '%Y-%m-%d'), type: :date }
.col-12.col-md-6
= f.input :local_time, label: 'Begins at', required: true, input_html: { value: @workshop.time.try(:strftime, '%H:%M'), type: :time }
= f.input :local_time, label: 'Begins at', required: true, input_html: { value: @workshop.local_time.presence || @workshop.time.try(:strftime, '%H:%M'), type: :time }
.col-12.col-md-6
= f.input :local_end_time, label: 'Ends at', required: true, input_html: { value: @workshop.ends_at.try(:strftime, '%H:%M'), type: :time }
= f.input :local_end_time, label: 'Ends at', required: true, input_html: { value: @workshop.local_end_time.presence || @workshop.ends_at.try(:strftime, '%H:%M'), type: :time }
.col-12#host
= f.input :host, as: :select, collection: Sponsor.all, include_blank: true, selected: (@workshop.host.id rescue '')
.col-12
Expand All @@ -27,11 +27,11 @@
%p.small.text-muted= t('admin.workshop.form.rsvp_details')
.row
.col-12.col-md-6
= f.input :rsvp_open_local_date, label: 'Open date', input_html: { value: @workshop.rsvp_opens_at.try(:strftime, '%Y-%m-%d'), type: :date }
= f.input :rsvp_open_local_date, label: 'Open date', input_html: { value: @workshop.rsvp_open_local_date.presence || @workshop.rsvp_opens_at.try(:strftime, '%Y-%m-%d'), type: :date }
.col-12.col-md-6
= f.input :rsvp_open_local_time, label: 'Open time', input_html: { value: @workshop.rsvp_opens_at.try(:time).try(:strftime, '%H:%M'), type: :time }
= f.input :rsvp_open_local_time, label: 'Open time', input_html: { value: @workshop.rsvp_open_local_time.presence || @workshop.rsvp_opens_at.try(:time).try(:strftime, '%H:%M'), type: :time }
.row
.col-12.col-md-6
= f.input :rsvp_close_local_date, label: 'Close date', input_html: { value: @workshop.rsvp_closes_at.try(:strftime, '%Y-%m-%d'), type: :date }
= f.input :rsvp_close_local_date, label: 'Close date', input_html: { value: @workshop.rsvp_close_local_date.presence || @workshop.rsvp_closes_at.try(:strftime, '%Y-%m-%d'), type: :date }
.col-12.col-md-6
= f.input :rsvp_close_local_time, label: 'Close time', input_html: { value: @workshop.rsvp_closes_at.try(:time).try(:strftime, '%H:%M'), type: :time }
= f.input :rsvp_close_local_time, label: 'Close time', input_html: { value: @workshop.rsvp_close_local_time.presence || @workshop.rsvp_closes_at.try(:time).try(:strftime, '%H:%M'), type: :time }
32 changes: 32 additions & 0 deletions spec/controllers/admin/workshops_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ def assigns(symbol)
end

describe 'POST #create' do
let(:sponsor) { Fabricate(:sponsor) }

it 'permits rsvp_close_local_date and rsvp_close_local_time' do
expect do
post :create, params: { workshop: { rsvp_close_local_date: '01/12/2020', rsvp_close_local_time: '15:00', host: '' } }
Expand All @@ -187,6 +189,36 @@ def assigns(symbol)
expect(PublicActivity::Activity.exists?(owner: admin, key: 'workshop.created',
trackable: created)).to be(true)
end

context 'when no chapter is selected' do
render_views

def create_workshop
post :create, params: {
workshop: {
chapter_id: '', local_date: '2026-09-21', local_time: '18:00',
local_end_time: '22:00', host: sponsor.id.to_s,
sponsor_ids: ['', sponsor.id.to_s], description: '',
rsvp_open_local_date: '', rsvp_open_local_time: '',
rsvp_close_local_date: '2026-09-21', rsvp_close_local_time: '14:30',
virtual: '0', coach_spaces: '0', student_spaces: '0', invitable: '1'
}
}
end

it 'renders the form with a validation warning instead of raising' do
expect { create_workshop }.not_to raise_error
expect(response).to have_http_status(:ok)
expect(flash[:warning]).to include("Chapter can't be blank")
end

it 'keeps the submitted RSVP close values in the form' do
create_workshop

expect(response.body).to include('value="2026-09-21"')
expect(response.body).to include('value="14:30"')
end
end
end

describe 'DELETE #destroy' do
Expand Down
Loading