Skip to content

Commit

Permalink
Adopter fosterer form answers (#1256)
Browse files Browse the repository at this point in the history
* remove broadcast as it throws redis missing error in production; add dependent destroy on org

* Update associations and add migration to move adopter applications to belong to person

* Update AdopterApplication to use Person; update seeds for new associations

* refactor models, controllers, views, tests to handle new associations

* remove creation of form submission on adopter sign up

* implemenet routs, controllers, views and policies for staff to review form submissions and form answers;

* lint

* appease brakeman

* add tests; add form answer header

* update tests

* lint

* remove handling the nil person case, this should fail loudly as it should not occur

* remove partial as I am not using it

* move empty state text to translation file

* fix

* update foster links to fosterer data

* WIP

* Update to show csv_timestamp and import date and show HH MM on the submitted at in case someone submits a form twice in one day, then it is easiser to determine which answers you are looking at

* merge main

* remove creation of formsubmission on creation of adopter user in seeds

* lint

* working prototype, needs authorization

* add remaining translations

* add policy check; add association between FormAnswer and Person

* lint

* update icons

* lint

* fix routes

* lint

* update seeds to both have donate URL and form URL; create form answers partial

* policy tests

* lint

* update messagin on the third party form page

* fix spacing
  • Loading branch information
kasugaijin authored Dec 16, 2024
1 parent 5f8eaae commit dbcbeee
Show file tree
Hide file tree
Showing 14 changed files with 220 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Organizations
module AdopterFosterer
class FormAnswersController < Organizations::BaseController
layout "adopter_foster_dashboard"

before_action :context_authorize!
before_action :set_latest_form_submission

def index
@form_answers = authorized_scope(@latest_form_submission.form_answers)
end

private

def context_authorize!
authorize! with: Organizations::AdopterFosterer::FormAnswerPolicy
end

def set_latest_form_submission
@latest_form_submission = current_user.person.latest_form_submission
end
end
end
end
1 change: 1 addition & 0 deletions app/models/concerns/authorizable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def staff?(organization)
view_adopted_pets
read_pet_tasks
view_external_form
view_form_answers
].freeze

FOSTERER_PERMISSIONS = %i[
Expand Down
1 change: 1 addition & 0 deletions app/models/form_answer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@
class FormAnswer < ApplicationRecord
acts_as_tenant(:organization)
belongs_to :form_submission
has_one :person, through: :form_submission
end
13 changes: 13 additions & 0 deletions app/policies/organizations/adopter_fosterer/form_answer_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Organizations
module AdopterFosterer
class FormAnswerPolicy < ApplicationPolicy
relation_scope do |relation|
relation.joins(form_submission: :person).where(form_submissions: {person_id: user.person.id})
end

def index?
permission?(:view_form_answers)
end
end
end
end
10 changes: 9 additions & 1 deletion app/views/layouts/adopter_foster_dashboard.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,15 @@
<% if Current.organization.external_form_url.present? %>
<li class="nav-item">
<%= active_link_to adopter_fosterer_external_form_index_path(dashboard: true), class: "nav-link" do %>
<i class="fe fe-help-circle nav-icon"></i> My Info
<i class="fe fe-clipboard nav-icon"></i> Form
<% end %>

<% if current_user.person.latest_form_submission.present? %>
<li class="nav-item">
<%= active_link_to adopter_fosterer_form_answers_path, class: "nav-link" do %>
<i class="fe fe-clipboard nav-icon"></i> Form Responses
<% end %>
</li>
<% end %>
</li>
<% end %>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<div class="d-flex flex-column align-items-center mb-4">
<div class="my-4 mx-8">
<% if params[:dashboard] %>
<p><%= t("organizations.adopter_fosterer.form_instructions.dashboard") %></p>
<% else %>

<% if current_user.person.latest_form_submission.present? %>
<p class="fw-bold mb-0"><%= t('organizations.adopter_fosterer.form_instructions.previous_answers') %> <%= link_to t('general.here'), adopter_fosterer_form_answers_path %>.</p>
<p><%= t('organizations.adopter_fosterer.form_instructions.update_form_answers') %></p>
<% else %>
<p><%= t("organizations.adopter_fosterer.form_instructions.dashboard", user_email: current_user.email) %></p>
<% end %>

<% else %>
<p><%= t(
"organizations.adopter_fosterer.form_instructions.index",
organization_name: Current.tenant.name,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<%= render DashboardPageComponent.new do |c| %>
<% c.with_header_title { t('.header') } %>
<% c.with_body do %>

<p><%= t('.description') %> <%= link_to t("general.here"), adopter_fosterer_external_form_index_path(dashboard: true) %>.</p>

<div class="justify-content-md-between mb-4 mb-xl-0 gx-3">
<div class="row">
<% if @form_answers.present? %>
<h4><%= t(".submitted_on", date: @latest_form_submission.csv_timestamp.strftime("%Y-%m-%d"), time: @latest_form_submission.csv_timestamp.strftime("%H:%M")) %></h4>

<%= render partial: "organizations/shared/form_answers", collection: @form_answers, as: :form_answer %>
<% end %>
</div>
</div>
<% end %>
<% end %>
12 changes: 12 additions & 0 deletions app/views/organizations/shared/_form_answers.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="justify-content-md-between mb-2 gx-3">
<div class="card">
<div id="<%= dom_id form_answer %>"class="card-body d-flex flex-sm-row flex-column justify-content-between border-bottom">
<div class="d-flex align-items-center">
<div>
<strong class="fs-4" >Q: <%= form_answer.question_snapshot %></strong>
<p class="mb-0">A: <%= form_answer.value %> </p>
</div>
</div>
</div>
</div>
</div>
15 changes: 1 addition & 14 deletions app/views/organizations/staff/form_answers/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
<%= turbo_frame_tag :form_answers do %>
<h4>Form Answers (<%= @form_submission.csv_timestamp.strftime("%Y-%m-%d") %> at <%= @form_submission.csv_timestamp.strftime("%H:%M") %>)</h4>

<% @form_answers.each do |form_answer| %>
<div class="justify-content-md-between mb-2 gx-3">
<div class="card">
<div id="<%= dom_id form_answer %>"class="card-body d-flex flex-sm-row flex-column justify-content-between border-bottom">
<div class="d-flex align-items-center">
<div>
<strong class="fs-4" >Q: <%= form_answer.question_snapshot %></strong>
<p class="mb-0">A: <%= form_answer.value %> </p>
</div>
</div>
</div>
</div>
</div>
<% end %>
<%= render partial: "organizations/shared/form_answers", collection: @form_answers, as: :form_answer %>
<% end %>
9 changes: 8 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,11 @@ en:
withdrew_by_accident_html: "If you withdrew by accident, <a href='/contact'>contact us</a>"
remove: "Remove"
withdraw: "Withdraw"
form_answers:
index:
header: "Form Responses"
description: "These are the responses from the last time you completed the questionnaire. Please review for accuracy. If changes are required, please fill out a new form"
submitted_on: "Submitted on %{date} at %{time}"
likes:
index:
header_title: 'Liked Pets'
Expand All @@ -718,7 +723,9 @@ en:
body_text: "At %{organization_name}, we’re dedicated to rescuing, rehabilitating, and rehoming animals in need. Your support helps us provide care, love, and hope to these pets until they find their forever homes."
form_instructions:
index: "Please complete this form using the same email address you signed up with. %{organization_name} needs this information in order to process your application(s)."
dashboard: If you need to update your information, you can do so by filling out a new copy of this form. Please only submit a new copy if there has been a change. Please ensure the email you use in the form is the same as the email on your account on this website. Unnecessary submissions may delay the processing of your application(s).
previous_answers: "You have already completed this form. View your responses"
update_form_answers: "Please only submit this form again if your details have changed and need updating."
dashboard: "Please complete this form so we have sufficient information to begin processing your adoption applications. Please ensure to use the same email address in the form as you did to register on this website (%{user_email})."
attachments:
purge:
success: "Attachment removed"
Expand Down
88 changes: 50 additions & 38 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,72 @@
Rails.application.routes.draw do
mount LetterOpenerWeb::Engine, at: "/letters" if Rails.env.development?

# Authentication
devise_for :users, controllers: {
registrations: "registrations",
sessions: "users/sessions",
invitations: "organizations/staff/invitations"
}

# Application Scope
resources :countries, only: [] do
resources :states, only: [:index]
end

root "root#index"
get "/up", to: "root#up" # Health check endpoint to let Kamal know the app is up
get "/about_us", to: "static_pages#about_us"
get "/partners", to: "static_pages#partners"
get "/donate", to: "static_pages#donate"
get "/privacy_policy", to: "static_pages#privacy_policy"
get "/terms_and_conditions", to: "static_pages#terms_and_conditions"
get "/cookie_policy", to: "static_pages#cookie_policy"

# Contact Forms
resources :contacts, only: %i[new create]
resource :organization_account_request, only: %i[new create]
resources :feedback, only: %i[new create]

# Organization Scope
scope module: :organizations do
# Public Routes
resources :home, only: [:index]
resources :adoptable_pets, only: %i[index show]
resources :faq, only: [:index]

# Staff Routes
namespace :staff do
resource :organization, only: %i[edit update]
resource :custom_page, only: %i[edit update]
resources :profile_reviews, only: [:show]
resources :external_form_upload, only: %i[index create]
resources :default_pet_tasks
resources :faqs
resources :matches, only: %i[create destroy]
resources :adoption_application_reviews, only: %i[index edit update]
resources :manage_fosters, only: %i[new create index edit update destroy]
resources :fosterers, only: %i[index edit update]
resources :adopters, only: %i[index]
resources :staff_invitations, only: %i[new]
resources :fosterer_invitations, only: %i[new]
post "user_roles/:id/to_admin", to: "user_roles#to_admin", as: "user_to_admin"
post "user_roles/:id/to_super_admin", to: "user_roles#to_super_admin", as: "user_to_super_admin"

resources :pets do
resources :tasks
post "attach_images", on: :member, to: "pets#attach_images"
post "attach_files", on: :member, to: "pets#attach_files"
end

resources :default_pet_tasks
resources :faqs
resources :dashboard, only: [:index] do
collection do
get :pets_with_incomplete_tasks
get :pets_with_overdue_tasks
end
end
resources :matches, only: %i[create destroy]

resources :people do
resources :form_submissions, only: [:index]
end

resources :people do
resources :form_submissions, only: [:index]
Expand All @@ -46,66 +80,44 @@
resources :manage_fosters, only: %i[new create index edit update destroy]
resources :fosterers, only: %i[index edit update]
resources :adopters, only: %i[index]
resources :form_submissions do
resources :form_answers, only: [:index]
end

resources :staff do
patch "update_activation"
end

resources :staff_invitations, only: %i[new]
resources :fosterer_invitations, only: %i[new]

namespace :custom_form do
resources :forms do
resources :questions
end
end
post "user_roles/:id/to_admin", to: "user_roles#to_admin", as: "user_to_admin"
post "user_roles/:id/to_super_admin", to: "user_roles#to_super_admin", as: "user_to_super_admin"
end

delete "staff/attachments/:id/purge", to: "attachments#purge", as: "staff_purge_attachment"
delete "attachments/:id/purge_avatar", to: "attachments#purge_avatar", as: "purge_avatar"

# Adopter and Fosterer Routes
namespace :adopter_fosterer do
resource :profile, except: :destroy
resources :faq, only: [:index]
resources :donations, only: [:index]
resources :dashboard, only: [:index]
resources :likes, only: [:index, :create, :destroy]
resources :adopter_applications, path: "applications", only: %i[index create update]
resources :external_form, only: %i[index]
resources :form_answers, only: %i[index]

resources :adopted_pets, only: [:index] do
resources :files, only: [:index], module: :adopted_pets
resources :tasks, only: [:index], module: :adopted_pets
end

resources :fostered_pets, only: [:index] do
resources :files, only: [:index], module: :fostered_pets
resources :tasks, only: [:index], module: :fostered_pets
end
resources :external_form, only: %i[index]
end
end

resources :countries, only: [] do
resources :states, only: [:index]
# File Purging
delete "staff/attachments/:id/purge", to: "attachments#purge", as: "staff_purge_attachment"
delete "attachments/:id/purge_avatar", to: "attachments#purge_avatar", as: "purge_avatar"
end

#
# [edwin] - routes cause failures if you cannot find an asset because it matches
# for all 404s, 422s, and 500s
#
# match "/404", to: "errors#not_found", via: :all
# match "/422", to: "errors#unprocessable_content", via: :all
# match "/500", to: "errors#internal_server_error", via: :all

root "root#index"
get "/up", to: "root#up" # Health check endpoint to let Kamal know the app is up
get "/about_us", to: "static_pages#about_us"
get "/partners", to: "static_pages#partners"
get "/donate", to: "static_pages#donate"
get "/privacy_policy", to: "static_pages#privacy_policy"
get "/terms_and_conditions", to: "static_pages#terms_and_conditions"
get "/cookie_policy", to: "static_pages#cookie_policy"

resources :contacts, only: %i[new create]
resource :organization_account_request, only: %i[new create]
resources :feedback, only: %i[new create]
end
3 changes: 2 additions & 1 deletion db/seeds/01_alta.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
email: "[email protected]",
phone_number: "201 555 8212",
custom_page: CustomPage.new(hero: "Where every paw finds a home", about: "Alta was founded by an incredible group of ladies in April of 2020. Our initial goal was to have both a rescue and a spay/neuter clinic, however, we quickly realized that it would be more efficient to separate into two organizations."),
external_form_url: "https://docs.google.com/forms/d/e/1FAIpQLSf9bI-kboxyQQB5I1W5pt0R25u9pHoXI7o3jQHKu1P4K-61mA/viewform?embedded=true"
external_form_url: "https://docs.google.com/forms/d/e/1FAIpQLSf9bI-kboxyQQB5I1W5pt0R25u9pHoXI7o3jQHKu1P4K-61mA/viewform?embedded=true",
donation_url: "https://wwww.example.com/"
)

ActsAsTenant.with_tenant(@organization) do
Expand Down
4 changes: 3 additions & 1 deletion db/seeds/02_baja.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
slug: "baja",
email: "[email protected]",
phone_number: "201 555 8212",
custom_page: CustomPage.new(hero: "hero text", about: "about us text")
custom_page: CustomPage.new(hero: "hero text", about: "about us text"),
external_form_url: "https://docs.google.com/forms/d/e/1FAIpQLSf9bI-kboxyQQB5I1W5pt0R25u9pHoXI7o3jQHKu1P4K-61mA/viewform?embedded=true",
donation_url: "https://wwww.example.com/"
)

ActsAsTenant.with_tenant(@organization) do
Expand Down
Loading

0 comments on commit dbcbeee

Please sign in to comment.