Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup basic route/view/controller for mentee application states #447

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<li class="border-2 flex flex-col p-4 mb-8 gap-2 shadow-lg">
<%= link_to link_text, mentee_application, class: 'font-bold text-lg text-secondary underline hover:no-underline' %>
<%= link_to link_text,
user_mentee_application_mentee_application_state_path(user_mentee_application_id: mentee_application.id, status_name: mentee_application.current_state),
class: 'font-bold text-lg text-secondary underline hover:no-underline' %>
<p>Status: <%= mentee_application.status.humanize %></p>
<p>Submitted: <%= mentee_application.created_at.to_fs(:slash_format) %></p>
</li>
Original file line number Diff line number Diff line change
@@ -1,42 +1,16 @@
class UserMenteeApplications::MenteeApplicationStatesController < ApplicationController
before_action :load_user_mentee_application
before_action -> { authorize :user_only, :application_reviewer? }
skip_before_action :only_authorize_agent

def new; end

# rubocop:disable Metrics/AbcSize
def create
respond_to do |format|
MenteeApplicationTransitionService.call(
application: @user_mentee_application,
reviewer: current_user,
action: application_state_params[:reviewer_action].to_sym,
note: application_state_params[:note]
)
@user_mentee_application.reload
format.html { redirect_to user_mentee_applications_path }
format.turbo_stream do
flash.now[:notice] = "Application updated to #{@user_mentee_application.current_state.status.humanize.downcase}"
end
rescue MenteeApplicationTransitionService::InvalidTransitionError => e
format.html do
redirect_to new_user_mentee_applications_mentee_application_state_path(@user_mentee_application),
alert: e.message
end
format.turbo_stream { flash.now[:alert] = e.message }
end
def show
@state = @user_mentee_application.mentee_application_states.find_by!(status: params[:status_name])
@previous_state = @state.previous_state
@next_state = @state.next_state
end
# rubocop:enable Metrics/AbcSize

private

def load_user_mentee_application
@user_mentee_application = UserMenteeApplication.find(params[:user_mentee_application_id])
end

def application_state_params
params
.permit(:reviewer_action, :note)
.merge(status_changed_id: current_user.id)
@user_mentee_application = current_user.mentee_applications.find(params[:user_mentee_application_id])
end
end
16 changes: 16 additions & 0 deletions app/models/mentee_application_state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,20 @@ class MenteeApplicationState < ApplicationRecord
def valid_transitions
MenteeApplicationTransitionService.valid_transitions(status:)
end

def future_state
MenteeApplicationTransitionService.future_state(status:)
end

def next_state
user_mentee_application.mentee_application_states.where('created_at > ?', created_at).order(:created_at).first
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods could arguably go on the user_mentee_application, but it'd have to accept a parameter for the state. This is one thing I'm not too sure about.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are fine for now

end

def previous_state
user_mentee_application.mentee_application_states.where('created_at < ?', created_at).order(:created_at).last
end

def to_param
status
end
end
5 changes: 5 additions & 0 deletions app/services/mentee_application_transition_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ def valid_transitions(status:)
STATUS_TRANSITION_MAPPING[status][:valid_transitions]
end

def future_state(status:)
status = status.to_sym
STATUS_TRANSITION_MAPPING[status][:promote_transition]
end

private

def code_challenge_sent_side_effects(application)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<div class="text-center">
<h1 class="text-xl font-bold"><%= current_user.full_name %></h1>
<h2 class="text-lg">Application Status</h2>
</div>

<div class="text-center">
<% if @previous_state.present? %>
<p>The previous state is <%= link_to @previous_state.status.humanize, user_mentee_application_mentee_application_state_path(user_mentee_application_id: @user_mentee_application.id, status_name: @previous_state) %></p>
<% end %>

<p>Current State: <%= @state.status.humanize %></p>

<% if @next_state.present? %>
<p>The next state is <%= link_to @next_state.status.humanize, user_mentee_application_mentee_application_state_path(user_mentee_application_id: @user_mentee_application.id, status_name: @next_state) %></p>
<% else %>
<p>The next state is <%= @state.future_state.to_s.humanize %></p>
<% end %>
</div>

<div class="p-2 max-w-prose mx-auto">
<%= t("#{@state.status}.applicant_information").html_safe %>
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
en:
application_received:
applicant_information: "
<h3 class='text-xl mt-4'>What is our Mission?</h3>
<p>At AOL, we bridge the gap between learning and doing. We team up junior developers with seasoned mentors to tackle real-world projects, ensuring that every member not only gains invaluable experience but becomes an integral part of a community that champions each other's growth and success in the tech industry.</p>
<h3 class='text-xl mt-4'>Who would be a good fit?</h3>
<ol class='list-decimal list-inside'>
<li><span class='font-bold'>Aspiring Developers</span>: Individuals who are passionate about coding and technology, looking for real-world experience. They could be recent graduates, self-taught programmers, or career switchers aiming to break into the tech industry.</li>
<li><span class='font-bold'>Continuous Learners</span>: Those who have a genuine curiosity and drive to continuously upskill, learn from others, and share their knowledge.</li>
<li><span class='font-bold'>Team Players</span>: Given the collaborative nature of projects, individuals who communicate well, are open to feedback, and can work effectively in a team would thrive in AOL.</li>
<li><span class='font-bold'>Solution Seekers</span>: Members who are proactive, ready to tackle challenges head-on, and are always looking for innovative solutions.</li>
<li><span class='font-bold'>Community-Focused Individuals</span>: Those who believe in giving back. This includes experienced developers who've landed jobs and are keen on mentoring, guiding, and sharing their experiences with newcomers.</li>
<li><span class='font-bold'>Adaptable and Resilient</span>: The tech world is ever-evolving, and projects can be unpredictable. Members who are adaptable to new technologies, methodologies, and can handle setbacks with a positive attitude would be ideal.</li>
<li><span class='font-bold'>Ethical and Respectful</span>: Given the diverse nature of most tech communities. it's crucial for members to uphold a standard of respect, understanding, and integrity, ensuring a safe and inclusive environment for all.</li>
</ol>
<p>In essence, AOL would be perfect for those who are keen on growing both technically and personally, while valuing the strength of a supportive community.</p>
<h3 class='text-xl mt-4'>What happens if you don't get accepted?</h3>
<p>If you are not accepted, we will try to give you feedback over email. Our goal is your success. It's common for people to re-apply later and be accepted.</p>
"
JoshDevHub marked this conversation as resolved.
Show resolved Hide resolved
status_description: "We received the application and it is awaiting reviewal."
acceptance_criteria:
"<p>After reviewing, click <strong>promote</strong> to:</p>
Expand Down
6 changes: 5 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@
end
end

resources :user_mentee_applications, only: %i[index show new create edit update]
resources :user_mentee_applications, only: %i[index show new create edit update] do
scope module: :user_mentee_applications do
resources :mentee_application_states, only: %i[show], param: :status_name
end
end

scope controller: :static do
get :faq
Expand Down
1 change: 1 addition & 0 deletions config/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
"./app/javascript/**/*.js",
"./app/views/**/*.{erb,haml,html,slim}",
"./app/components/**/*.{rb,erb,html}",
"./config/locales/**/*.yml"
],
theme: {
extend: {
Expand Down
80 changes: 80 additions & 0 deletions spec/models/mentee_application_state_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# == Schema Information
#
# Table name: mentee_application_states
#
# id :bigint not null, primary key
# note :text
# status :integer default("application_received"), not null
# created_at :datetime not null
# updated_at :datetime not null
# status_changed_id :bigint
# user_mentee_application_id :bigint not null
#
# Indexes
#
# index_mentee_application_states_on_status_changed_id (status_changed_id)
# index_mentee_application_states_on_user_mentee_application_id (user_mentee_application_id)
#
# Foreign Keys
#
# fk_rails_... (status_changed_id => users.id)
# fk_rails_... (user_mentee_application_id => user_mentee_applications.id)
require 'rails_helper'

RSpec.describe MenteeApplicationState do
let(:user) { create(:user) }
let(:mentee_application) { create(:user_mentee_application) }
let(:mentee_application_state) { create(:mentee_application_state, user_mentee_application: mentee_application) }

context 'when status is application received' do
describe 'future_state' do
it 'returns the future state as coding challenge sent' do
expect(mentee_application_state.future_state).to eq(:coding_challenge_sent)
end
end

describe 'next_state' do
it 'returns the next state as nil' do
expect(mentee_application_state.next_state).to be_nil
end
end

describe 'previous_state' do
it 'returns the current state' do
expect(mentee_application_state.previous_state.status.to_sym).to eq(:application_received)
end
end
end

context 'when status is coding challenge sent' do
let(:mentee_application_state) do
create(:mentee_application_state, :coding_challenge_sent, user_mentee_application: mentee_application)
end

describe 'future_state' do
it 'returns the future state as coding_challenge_received' do
expect(mentee_application_state.future_state).to eq(:coding_challenge_received)
end
end

describe 'next_state' do
it 'returns the next state as coding_challenge_completed' do
expect(mentee_application_state.next_state).to be_nil
end

context 'when the user is on application_received state' do
let(:previous_mentee_application_state) { mentee_application_state.previous_state }

it 'returns the next state as coding_challenge_sent' do
expect(previous_mentee_application_state.next_state.status.to_sym).to eq(:coding_challenge_sent)
end
end
end

describe 'previous_state' do
it 'returns the previous state as application_received' do
expect(mentee_application_state.previous_state.status.to_sym).to eq(:application_received)
end
end
end
end