Skip to content
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7978f79
add attributes for dietary restrictions to Member
mikej Aug 20, 2025
d2e9108
add dietary restrictions to member form
mikej Aug 21, 2025
bfd4d55
display dietary restrictions on workshop admin page
mikej Aug 21, 2025
7ba07b7
add bottom margin to vertical collections
mikej Aug 21, 2025
dc25914
add input for specifying other dietary restrictions
mikej Aug 21, 2025
c3a0317
feat: add description to invitation emails
davidmillen50 Aug 18, 2025
78930b0
chore: remove some unrelated changes
davidmillen50 Aug 18, 2025
273ad56
chore: add margin to description text
davidmillen50 Aug 18, 2025
490f7a8
Show/hide "Other dietary restrictions"
mikej Aug 22, 2025
10541c9
Add dietary restrictions method to MemberPresenter
mikej Aug 22, 2025
5992ab9
update to use `class_names` helper
mikej Aug 22, 2025
ae2a8f3
rename variable for clarity
mikej Aug 22, 2025
c1a65bf
focus the "other dietary restrictions" input
mikej Aug 22, 2025
72fad24
Allow long "other dietary restrictions" to wrap
mikej Aug 22, 2025
42c7c77
add validation for other dietary restrictions
mikej Aug 22, 2025
9d479db
replace change_table with add_column in migration
mikej Aug 26, 2025
2c1f7fb
use MemberPresenter when showing user profile
mikej Aug 26, 2025
fbf734f
show dietary restrictions on current user profile
mikej Aug 26, 2025
edd366c
show dietary restrictions in admin member profiles
mikej Aug 26, 2025
5591992
ask for dietary restrictions during signup
mikej Aug 26, 2025
53781a9
Merge branch 'codebar:master' into dietary-restrictions
mikej Aug 26, 2025
15c05a4
use humanize and upcase_first for checkbox labels
mikej Aug 26, 2025
577c05e
Merge branch 'dietary-restrictions' of github.com:mikej/codebar-plann…
mikej Aug 26, 2025
d0b41b2
add comment to explain intention in member_params
mikej Aug 27, 2025
1d1f8cb
add system tests for updating dietary restrictions
mikej Aug 27, 2025
17f5020
add link to update dietary restrictions on invite
mikej Aug 27, 2025
649a8f8
remove some unused i18n strings
mikej Aug 27, 2025
1acabf6
Merge branch 'master' into dietary-restrictions
mikej Aug 27, 2025
882c077
test to display of attendee dietary restrictions
mikej Aug 27, 2025
18652fa
fix typo in expectation
mikej Aug 28, 2025
e006160
update interpolation argument to pass link
mikej Aug 28, 2025
7815915
update to check for expected dietary restrictions
mikej Aug 28, 2025
3bbffda
Merge branch 'master' into dietary-restrictions
mikej Aug 28, 2025
d1c9266
test setting dietary restrictions during signup
mikej Aug 28, 2025
1d41738
minor edit to comment wording
mikej Aug 28, 2025
9cbabc3
update skill badges on admin member profile
mikej Aug 28, 2025
714f975
use text-break for dietary restriction badges
mikej Aug 28, 2025
3fabf63
update to use hint and placeholder for Skills field
mikej Aug 29, 2025
eda5dcc
make displayed_dietary_restrictions nil-safe
mikej Aug 29, 2025
fff4f13
Revert "update to use hint and placeholder for Skills field"
mikej Sep 1, 2025
de1cfa9
Update migration to reflect current version of Rails
mikej Sep 16, 2025
9215f51
Merge branch 'master' into dietary-restrictions
mikej Sep 16, 2025
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/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
//= require pickadate/picker.time
//= require subscriptions-toggle
//= require invitations
//= require dietary-restrictions
//= require cocoon
//= require font_awesome5

Expand Down
12 changes: 12 additions & 0 deletions app/assets/javascripts/dietary-restrictions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
$(document).ready(function() {
$('#member_dietary_restrictions_other').on('change', function () {
const $otherDietaryRestrictions = $('#member_other_dietary_restrictions');
const $elementToToggle = $otherDietaryRestrictions.parent();
if ($elementToToggle.hasClass('d-none')) {
$elementToToggle.removeClass('d-none').hide().slideDown(50);
$otherDietaryRestrictions.focus();
} else {
$elementToToggle.slideUp(50, () => $elementToToggle.addClass('d-none'));
}
});
});
6 changes: 6 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@
$primary: $dark-codebar-blue !default;

@import "bootstrap-custom";

/* Bootstrap's Reboot sets legends to float: left, which puts the first check box in a fieldset off to the
right instead of underneath the legend. This overrides that. */
legend {
float: none !important;
}
2 changes: 1 addition & 1 deletion app/controllers/admin/members_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def index
end

def show
@member = Member.find(params[:id])
@member = MemberPresenter.new(Member.find(params[:id]))
load_attendance_data(@member)

@actions = admin_actions(@member).sort_by(&:created_at).reverse
Expand Down
12 changes: 10 additions & 2 deletions app/controllers/concerns/member_concerns.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@ module InstanceMethods

def member_params
params.require(:member).permit(
:pronouns, :name, :surname, :email, :mobile, :about_you, :skill_list, :newsletter
)
:pronouns, :name, :surname, :email, :mobile, :about_you, :skill_list, :newsletter, :other_dietary_restrictions,
dietary_restrictions: [],
).tap do |params|
# We want to keep Rails' hidden blank field in the form so that all dietary restrictions for a member can be
# removed by submitting the form with all check boxes unticked. However, we want to remove the blank value
# before setting the dietary restrictions attribute on the model.
# See Gotcha section here:
# https://api.rubyonrails.org/v7.1/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes
params[:dietary_restrictions] = params[:dietary_restrictions].reject(&:blank?) if params[:dietary_restrictions]
end
end

def suppress_notices
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/members_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class MembersController < ApplicationController
include MemberConcerns

before_action :set_member, only: %i[edit step2 profile update]
before_action :set_member, only: %i[edit step2 update]
before_action :authenticate_member!, only: %i[edit step2 profile]
before_action :suppress_notices, only: %i[step2]

Expand All @@ -20,6 +20,7 @@ def step2
end

def profile
@member = MemberPresenter.new(current_user)
render :show
end

Expand Down
8 changes: 8 additions & 0 deletions app/models/member.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class Member < ApplicationRecord
validates :email, uniqueness: true
validates :about_you, length: { maximum: 255 }

DIETARY_RESTRICTIONS = %w[vegan vegetarian pescetarian halal gluten_free dairy_free other].freeze
validates_inclusion_of :dietary_restrictions, in: DIETARY_RESTRICTIONS
validates_presence_of :other_dietary_restrictions, if: :other_dietary_restrictions?

scope :accepted_toc, -> { where.not(accepted_toc_at: nil) }
scope :order_by_email, -> { order(:email) }
scope :subscribers, -> { joins(:subscriptions).order('created_at desc').uniq }
Expand Down Expand Up @@ -118,6 +122,10 @@ def recent_notes
member_notes.where('created_at > ?', notes_from_date)
end

def other_dietary_restrictions?
dietary_restrictions.present? && dietary_restrictions.include?('other')
end

def self.find_members_by_name(name)
name.strip!
name.eql?('') ? self.none : where("CONCAT(name, ' ', surname) ILIKE ?", "%#{name}%")
Expand Down
8 changes: 8 additions & 0 deletions app/presenters/member_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ def pairing_details_array(role, tutorial, note)
role.eql?('Coach') ? coach_pairing_details(note) : student_pairing_details(tutorial, note)
end

def displayed_dietary_restrictions
return [] if dietary_restrictions.nil?

(dietary_restrictions - ['other']).map(&:humanize).tap do |drs|
drs << other_dietary_restrictions if other_dietary_restrictions? && other_dietary_restrictions.present?
end.map(&:upcase_first)
end

private

def coach_pairing_details(note)
Expand Down
10 changes: 9 additions & 1 deletion app/views/admin/members/_profile.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@
.mb-4
%h5 Skills
- @member.skills.each do |skill|
.badge.bg-success= skill.name
.badge.bg-secondary= skill.name

.mb-4
%h5 Dietary Restrictions
- if @member.dietary_restrictions.present?
- @member.displayed_dietary_restrictions.each do |dr|
.badge.bg-secondary.text-wrap.text-break.mb-1.text-start= dr
- else
.text-muted None

- if @workshop_attendances.positive? || @meeting_rsvps.positive? || @event_rsvps.positive?
.attendance-summary.mt-4
Expand Down
4 changes: 4 additions & 0 deletions app/views/admin/workshop/_attendances.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
= invitation.member.email
- else
= invitation.member.full_name
- if invitation.member.dietary_restrictions.present?
%p
- invitation.member.displayed_dietary_restrictions.each do |dr|
%span.badge.bg-secondary.text-wrap.text-break.mb-1.text-start= dr
.col-6
- if invitation.tutorial?
%p.mb-1 Tutorial: #{invitation.tutorial}
Expand Down
2 changes: 1 addition & 1 deletion app/views/invitation/_coach.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
- if @workshop.virtual?
= t('workshop.virtual.invitation.shared_intro_3_html', email_link: mail_to(@workshop.chapter.email, @workshop.chapter.email))
- else
%p= t('workshop.invitation.shared_intro_4_html', email_link: mail_to(@workshop.chapter.email, @workshop.chapter.email).html_safe)
%p= t('workshop.invitation.shared_intro_4_html', update_your_details_link: link_to(t('members.update_your_details_lower'), edit_member_path).html_safe)
2 changes: 1 addition & 1 deletion app/views/invitation/_student.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
%p= t('workshop.virtual.invitation.shared_intro_3_html', email_link: mail_to(@workshop.chapter.email, @workshop.chapter.email))
- else
%p= t('workshop.invitation.student_intro_3_html')
%p= t('workshop.invitation.shared_intro_4_html', email_link: mail_to(@workshop.chapter.email, @workshop.chapter.email).html_safe)
%p= t('workshop.invitation.shared_intro_4_html', update_your_details_link: link_to(t('members.update_your_details_lower'), edit_member_path).html_safe)
4 changes: 4 additions & 0 deletions app/views/member/details/edit.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
= f.input :about_you, as: :text, label: t('member.details.edit.coach.about_you'), input_html: { rows: 3 }, required: true
- else
= f.input :about_you, as: :text, label: t('member.details.edit.student.about_you'), input_html: { rows: 3 }, required: true
= f.input :dietary_restrictions, collection: Member::DIETARY_RESTRICTIONS, as: :check_boxes,
label_method: ->(r) { r.humanize.upcase_first }
= f.input :other_dietary_restrictions, placeholder: 'Other dietary restrictions',
wrapper_html: { class: class_names('mt-n3', 'd-none': !@member.other_dietary_restrictions?) }, label_html: { class: 'sr-only' }
= f.input :newsletter, as: :boolean, checked_value: true, unchecked_value: false
.text-right.mb-4
= hidden_field_tag :next_page, step2_member_path(member_type: @type)
Expand Down
7 changes: 6 additions & 1 deletion app/views/members/_new.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@
= f.input :mobile
.col-12
= f.input :about_you, as: :text, label: 'Tell us a little bit about yourself', input_html: { rows: 3 }, required: true
.col-12
= f.input :dietary_restrictions, collection: Member::DIETARY_RESTRICTIONS, as: :check_boxes,
label_method: ->(r) { r.humanize.upcase_first }
= f.input :other_dietary_restrictions, placeholder: 'Other dietary restrictions',
wrapper_html: { class: class_names('mt-n3', 'd-none': !@member.other_dietary_restrictions?) }, label_html: { class: 'sr-only' }
- if @member.coach?
.col-12
= f.input :skill_list, label: 'Skills, enter as a comma separated list', input_html: { value: @member.skill_list.join(", ") }
= f.input :skill_list, input_html: { value: @member.skill_list.join(", ") }
.col-12.text-right
= f.button :button, submit_text, class: 'btn btn-primary'
8 changes: 8 additions & 0 deletions app/views/members/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@
- @member.skills.each do |skill|
.badge.bg-secondary= skill.name

%dt Dietary Restrictions
%dd.mb-3
- if @member.dietary_restrictions.present?
- @member.displayed_dietary_restrictions.each do |dr|
.badge.bg-secondary.text-wrap.text-break.mb-1.text-start= dr
- else
.text-muted None

= link_to 'Update your details', edit_member_path, class: 'btn btn-primary', role: 'button'

.col-12.col-md-4.offset-md-1.mb-4
Expand Down
2 changes: 1 addition & 1 deletion config/initializers/simple_form_bootstrap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
end

# vertical input for radio buttons and check boxes
config.wrappers :vertical_collection, item_wrapper_class: 'form-check', tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
config.wrappers :vertical_collection, item_wrapper_class: 'form-check', tag: 'fieldset', class: 'form-group mb-3', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
b.use :html5
b.optional :readonly
b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
Expand Down
1 change: 0 additions & 1 deletion config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ de:
q: "Ich werde pendeln. Können Sie mir bei meinen Reisekosten helfen?"
a: "Wir werden einige Reisestipendien anbieten. Bitte stellen dich sicher, dass du den Fragebogen ausfüllst, nachdem du dich angemeldet hast und wir werden uns mit dir in Verbindung setzen."
coaches:
want_to_coach: "Möchtest Du in unseren Workshops coachen?"
read_before: "Wenn Du unsere Workshops noch nicht besucht hast, lies bitte unseren"
code_of_conduct: "Verhaltenskodex"
policy: "da wir eine Nulltoleranzpolitik haben und von allen ein entsprechendes Verhalten erwarten. Das solltest Du lesen: Unser"
Expand Down
11 changes: 8 additions & 3 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ en:
student_intro_1: 'In our workshops, you will get to go through any of our available tutorials, ask for programming advice or get help on your own projects.'
student_intro_2: 'In case you are unable to attend after you RSVP, please make sure you come back and update your attendance. We have limited space and do a coaches request depending on the number of attending students.'
student_intro_3_html: 'Please make sure you <b>bring your laptop</b> with you.'
shared_intro_4_html: 'PS: There will also be food at the workshop. We always make an effort to have vegetarian, vegan and gluten-free options available. If you have any other dietary requirements, send us an email at %{email_link}.'
shared_intro_4_html: 'PS: There will also be food at the workshop. If you have any specific dietary restrictions, please %{update_your_details_link} to let us know about them.'
workshop_invitation:
coach_skills_tooltip: Keeping your skills up-to-date enables organisers to plan ahead and makes running workshops easier.
meeting:
Expand Down Expand Up @@ -302,13 +302,11 @@ en:
q: "I will be commuting. Can you help with my travel expenses?"
a: "We will be offering some travel grants. Just make sure you fill in the questionnaire after you RSVP and we will get in touch."
coaches:
want_to_coach: "Do you want to coach at our workshops?"
read_before: "If you have not attended our workshops before, make sure you read our"
code_of_conduct: "code of conduct"
policy: "as we have a zero tolerance policy and expect everyone to behave appropriately. You should also go through our"
guide: "coaching guide"
unable_attend: "In case you are unable to attend after you RSVP, please make sure you come back and update your attendance as we rely on coaches showing up in order for our workshops to run smoothly."
food: "PS: There will also be food at the workshop. We always make an effort to have vegetarian, vegan and gluten-free options available. If you have any other dietary requirements, send us email at"
code_of_conduct:
title: "Code of conduct"
summary:
Expand Down Expand Up @@ -336,6 +334,8 @@ en:
sign_up_as_student_disclaimer: "* I understand and meet the eligibility criteria."
sign_up_as_coach: "Join us as a coach"
code_of_conduct: "code of conduct"
update_your_details: "Update your details"
update_your_details_lower: "update your details"
new:
intro_html: "We provide a welcoming, inclusive, and supportive learning environment, with a strict zero-tolerance policy for any form of harassment or inappropriate behavior. Please take a moment to review our <a href='%{link}'>code of conduct</a> before signing up."
students:
Expand Down Expand Up @@ -671,6 +671,7 @@ en:
name: 'Grace'
surname: 'Hopper'
pronouns: 'e.g she/her/they'
skill_list: 'e.g. HTML, CSS, JavaScript, React, Ruby, Python, SQL'
job:
company: 'e.g. codebar'
company_website: 'e.g. https://codebar.io'
Expand All @@ -686,6 +687,7 @@ en:
hints:
member:
email: 'This is needed so we can email you invitations to our events'
skill_list: 'Enter as a comma separated list'
workshop_invitation:
note: 'Pairing preferences or anything else you think we should know.'
job:
Expand Down Expand Up @@ -721,6 +723,9 @@ en:
accessibility_info: Accessibility information
number_of_coaches: Coach spots
seats: Student spots
member:
skill_list: Skills
dietary_restrictions: If you have any dietary restrictions, let us know about them here
activerecord:
attributes:
job:
Expand Down
2 changes: 0 additions & 2 deletions config/locales/en_AU.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,11 @@ en-AU:
q: "I will be commuting. Can you help with my travel expenses?"
a: "We will be offering some travel grants. Just make sure you fill in the questionnaire after you RSVP and we will get in touch."
coaches:
want_to_coach: "Do you want to coach at our workshops?"
read_before: "If you have not attended our workshops before, make sure you read our"
code_of_conduct: "code of conduct"
policy: "as we have a zero tolerance policy and expect everyone to behave appropriately. You should also go through our"
guide: "coaching guide"
unable_attend: "In case you are unable to attend after you RSVP, please make sure you come back and update your attendance as we rely on coaches showing up in order for our workshops to run smoothly."
food: "PS: There will also be food at the workshop. We always make an effort to have vegetarian, vegan and gluten-free options available. If you have any other dietary requirements, send us email at"
code_of_conduct:
title: "Code of conduct"
summary:
Expand Down
2 changes: 0 additions & 2 deletions config/locales/en_GB.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,11 @@ en-GB:
q: "I will be commuting. Can you help with my travel expenses?"
a: "We will be offering some travel grants. Just make sure you fill in the questionnaire after you RSVP and we will get in touch."
coaches:
want_to_coach: "Do you want to coach at our workshops?"
read_before: "If you have not attended our workshops before, make sure you read our"
code_of_conduct: "code of conduct"
policy: "as we have a zero tolerance policy and expect everyone to behave appropriately. You should also go through our"
guide: "coaching guide"
unable_attend: "In case you are unable to attend after you RSVP, please make sure you come back and update your attendance as we rely on coaches showing up in order for our workshops to run smoothly."
food: "PS: There will also be food at the workshop. We always make an effort to have vegetarian, vegan and gluten-free options available. If you have any other dietary requirements, send us email at"
code_of_conduct:
title: "Code of conduct"
summary:
Expand Down
2 changes: 0 additions & 2 deletions config/locales/en_US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,11 @@ en-US:
q: "I will be commuting. Can you help with my travel expenses?"
a: "We will be offering some travel grants. Just make sure you fill in the questionnaire after you RSVP and we will get in touch."
coaches:
want_to_coach: "Do you want to coach at our workshops?"
read_before: "If you have not attended our workshops before, make sure you read our"
code_of_conduct: "code of conduct"
policy: "as we have a zero tolerance policy and expect everyone to behave appropriately. You should also go through our"
guide: "coaching guide"
unable_attend: "In case you are unable to attend after you RSVP, please make sure you come back and update your attendance as we rely on coaches showing up in order for our workshops to run smoothly."
food: "PS: There will also be food at the workshop. We always make an effort to have vegetarian, vegan and gluten-free options available. If you have any other dietary requirements, send us email at"
code_of_conduct:
title: "Code of conduct"
summary:
Expand Down
2 changes: 0 additions & 2 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,11 @@ es:
q: "Estaré viajando. ¿Me pueden ayudar con mis gastos de viaje?"
a: "Vamos a ofrecer algunas becas de viaje. Solo asegúrate de completar el cuestionario después de que RSVP y nos pondremos en contacto."
coaches:
want_to_coach: "¿Quieres formarte en nuestros talleres?"
read_before: "Si no ha asistido a nuestros talleres antes, asegúrate de leer nuestro"
code_of_conduct: "código de conducta"
policy: "Como tenemos una política de tolerancia cero y esperamos que todos se comporten de manera adecuada. También deberías pasar por nuestro"
guide: "guía para entrenadores"
unable_attend: "En caso de que no pueda asistir después de su RSVP, asegúrese de regresar y actualizar su asistencia a medida que confíe en los entrenadores que aparecen para que nuestros talleres se ejecuten sin problemas."
food: "También habrá comida en el taller. Siempre nos esforzamos en tener disponibles opciones vegetarianas, veganas y sin gluten. Si tiene otros requisitos dietéticos, envíenos un correo electrónico a"
code_of_conduct:
title: "Código de Conducta"
summary:
Expand Down
2 changes: 0 additions & 2 deletions config/locales/fi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,11 @@ fi:
q: "I will be commuting. Can you help with my travel expenses?"
a: "We will be offering some travel grants. Just make sure you fill in the questionnaire after you RSVP and we will get in touch."
coaches:
want_to_coach: "Do you want to coach at our workshops?"
read_before: "If you have not attended our workshops before, make sure you read our"
code_of_conduct: "code of conduct"
policy: "as we have a zero tolerance policy and expect everyone to behave appropriately. You should also go through our"
guide: "coaching guide"
unable_attend: "In case you are unable to attend after you RSVP, please make sure you come back and update your attendance as we rely on coaches showing up in order for our workshops to run smoothly."
food: "PS: There will also be food at the workshop. We always make an effort to have vegetarian, vegan and gluten-free options available. If you have any other dietary requirements, send us email at"
code_of_conduct:
title: "Code of conduct"
summary:
Expand Down
1 change: 0 additions & 1 deletion config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ fr:
q: "Je voyage de loin. Pouvez-vous m'aider avec mes frais de déplacements?"
a: "Nous offrons des bourses de voyage. Vous devez vous assurer de remplir le questionnaire après vous être enregistrer et nous vous contacterons."
coaches:
want_to_coach: "Voulez vous enseigner à nos ateliers?"
read_before: "Si vous n'êtes jamais venu a nos ateliers, merci de lire notre"
code_of_conduct: "code de conduite"
policy: "vu que nous attendons que chacun se comporte correctement. Vous devriez aussi lire notre"
Expand Down
Loading