Skip to content

Commit

Permalink
Merge pull request #56 from TreinaDev/feature/usuario-ve-convites
Browse files Browse the repository at this point in the history
Adiciona fluxo interno de resposta ao convite


Co-authored-by: Lucas Aguilar <lucasaguilar835@gmail.com>
  • Loading branch information
Luckvc and oLucasAguilar authored Feb 1, 2024
2 parents 33c139e + f7d3ef5 commit a505be8
Show file tree
Hide file tree
Showing 21 changed files with 705 additions and 64 deletions.
56 changes: 40 additions & 16 deletions app/controllers/invitations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,48 @@
class InvitationsController < ApplicationController
before_action :authenticate_user!, only: %i[create cancel]
before_action :set_invitation, only: %i[cancel]
before_action :set_project, only: %i[create cancel]
before_action :authorize_user, only: %i[create cancel]
before_action :authorize_cancel, only: %i[cancel]
before_action :set_invitation, only: %i[cancel show accept decline]
before_action :set_project, only: %i[create cancel accept decline]
before_action :authorize_leader, only: %i[create cancel]
before_action :authorize_invited, only: %i[show accept decline]

def index
@invitations = Invitation.where(profile_email: current_user.email).pending
end

def show
@invitation.validate_expiration_days
end

def create
create_invitation
if @invitation.save
return redirect_to project_portfoliorrr_profile_path(@invitation.project, @invitation.profile_id),
notice: t('.success')
end
flash[:alert] = invitation_error unless @invitation.save
flash[:notice] = t('.success') if @invitation.save

redirect_to project_portfoliorrr_profile_path(@invitation.project, @invitation.profile_id),
alert: invitation_error
redirect_to project_portfoliorrr_profile_path(@invitation.project, @invitation.profile_id)
end

def cancel
@invitation.cancelled!
if @invitation.cancelled!
redirect_to project_portfoliorrr_profile_path(@invitation.project, @invitation.profile_id), notice: t('.success')
else
redirect_to root_path, alert: t('.fail')
end
end

redirect_to project_portfoliorrr_profile_path(@invitation.project, @invitation.profile_id), notice: t('.success')
def accept
if @invitation.accepted!
@project.user_roles.create(user: User.find_by(email: @invitation.profile_email))
redirect_to project_path(@project), notice: t('.success')
else
redirect_to root_path, alert: t('.fail')
end
end

def decline
if @invitation.declined!
redirect_to invitations_path, notice: t('.success')
else
redirect_to root_path, alert: t('.fail')
end
end

private
Expand All @@ -46,16 +69,17 @@ def set_project
end
end

def authorize_user
def authorize_leader
redirect_to root_path unless @project.leader?(current_user)
end

def authorize_cancel
redirect_to root_path unless @invitation.pending?
def authorize_invited
redirect_to root_path unless @invitation.profile_email == current_user.email
end

def invitation_error
return t('.fail') if @invitation.expiration_days&.negative?
return t('.already_member') if @invitation.project.member?(@invitation.invitation_user)

t('.pending_invitation')
end
Expand Down
21 changes: 21 additions & 0 deletions app/models/invitation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class Invitation < ApplicationRecord
validates :profile_email, presence: true
validates :expiration_days, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
validate :check_pending_invitation, on: :create
validate :check_member, on: :create
validate :days_to_date, on: :create

enum status: { pending: 0, accepted: 1, declined: 2, cancelled: 3, expired: 4, removed: 5 }
Expand All @@ -18,10 +19,24 @@ def expired!
super if pending?
end

def accepted!
super if pending?
end

def declined!
super if pending?
end

def validate_expiration_days
return unless expiration_date

expired! if pending? && (Time.zone.today.after? expiration_date)
end

def invitation_user
User.find_by(email: profile_email)
end

private

def days_to_date
Expand All @@ -33,4 +48,10 @@ def check_pending_invitation

errors.add(:base, I18n.t('invitations.create.pending_invitation'))
end

def check_member
return unless project.member?(invitation_user)

errors.add(:base, I18n.t('invitations.already_member'))
end
end
30 changes: 30 additions & 0 deletions app/views/invitations/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<h1><%= Invitation.model_name.human(count: 2) %></h1>
<div class="container">
<div class="row">
<% if @invitations.any? %>
<% @invitations.each do |invitation| %>
<div class="col-sm-6 mb-3" >
<div class="card" style="height: 100%">
<div class="card-body">
<h4 class="card-title">
<%= link_to invitation.project.title, invitation_path(invitation) %>
</h4>
<h6 class="card-subtitle mb-2 text-muted ">
<%= Project.human_attribute_name :category %>: <%= invitation.project.category %>
</h6>
<p class="card-text">
<%= invitation.message %>
</p>
<p class="card-text">
<%= Invitation.human_attribute_name :expiration_date %>:
<%= invitation.expiration_date ? l(invitation.expiration_date) : I18n.t('invitations.no_expiration_date') %>
</p>
</div>
</div>
</div>
<% end %>
<% else %>
<h3><%= t('invitations.empty_state') %></h3>
<% end %>
</div>
</div>
34 changes: 34 additions & 0 deletions app/views/invitations/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<p>
<strong><%= @invitation.project.title %>: </strong>
<%= @invitation.project.description %>
</p>
<p>
<strong><%= Project.human_attribute_name :category %>: </strong>
<%= @invitation.project.category %>
</p>
<p>
<% unless @invitation.message.blank? %>
<strong><%= Invitation.human_attribute_name :message %>: </strong>
<%= @invitation.message %>
<% end %>
</p>
<p>
<strong><%= Invitation.human_attribute_name :expiration_date %>: </strong>
<%= @invitation.expiration_date ? l(@invitation.expiration_date) : I18n.t('invitations.no_expiration_date') %>
</p>

<% if @invitation.pending? %>
<div class="d-flex mb-3">
<%= button_to I18n.t('invitations.accept_btn'),
accept_invitation_path(@invitation), method: :patch,
class: 'btn btn-success me-2' %>
<%= button_to I18n.t('invitations.decline_btn'),
decline_invitation_path(@invitation), method: :patch,
class: 'btn btn-danger me-2' %>
</div>
<% end %>

<%= t('invitations.cancelled') if @invitation.cancelled? %>
<%= t('invitations.expired') if @invitation.expired? %>
<%= t('invitations.accepted') if @invitation.accepted? %>
<%= t('invitations.declined') if @invitation.declined? %>
5 changes: 5 additions & 0 deletions app/views/layouts/_navbar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
projects_path,
class:"nav-link" %>
</li>
<li class="nav-item">
<%= link_to Invitation.model_name.human(count: 2),
invitations_path,
class:"nav-link" %>
</li>
<li class="nav-item">
<%= link_to t(:my_profile),
profile_path(current_user.profile),
Expand Down
15 changes: 12 additions & 3 deletions app/views/portfoliorrr_profiles/_invitation_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@

<% if current_invitation.present? %>
<p><%= I18n.t('invitations.create.pending_invitation') %></p>
<p><%= Invitation.human_attribute_name :message %>: <%= current_invitation.message %></p>
<p><%= Invitation.human_attribute_name :expiration_date %>: <%= I18n.l(current_invitation.expiration_date) %></p>
<%= button_to I18n.t('invitations.cancel_button'), cancel_invitation_path(current_invitation.id), method: :patch, class: 'btn btn-danger' %>

<% unless current_invitation.message.blank? %>
<p><%= Invitation.human_attribute_name :message %>: <%= current_invitation.message %></p>
<% end %>

<p>
<%= Invitation.human_attribute_name :expiration_date %>:
<%= current_invitation.expiration_date ? l(current_invitation.expiration_date) : I18n.t('invitations.no_expiration_date') %>
</p>

<%= button_to I18n.t('invitations.cancel_button'), cancel_invitation_path(current_invitation.id),
method: :patch, class: 'btn btn-danger' %>
<% else %>
<%= form_with(model: invitation, url: project_portfoliorrr_profile_invitations_path(project, profile.id), local: true) do |form| %>
<div class="mb-3">
Expand Down
2 changes: 1 addition & 1 deletion app/views/portfoliorrr_profiles/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<div class="card-body">
<h4><%= category.name %></h4>
<hr>
<h6><%= category.description %></h6>
<h6><%= category.description %></h6>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/views/projects/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<% @projects.each do |project| %>
<div class="col-sm-6 mb-3">
<div class="card" style="height: 100%">
<div class="card-body">
<div class="card-body" >
<h4 class="card-title"><%= link_to project.title, project_path(project) %></h4>
<h6 class="card-subtitle mb-2 text-muted "><%= Project.human_attribute_name :category %>: <%= project.category %></h6>
<p class="card-text"><%= project.description %></p>
Expand Down
1 change: 1 addition & 0 deletions config/locales/general.pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ pt-BR:
try_again_later: Tente novamente mais tarde
profile: Perfil de %{name}
profile_not_available: Perfil não disponível
model_description: Descrição do %{model}
20 changes: 18 additions & 2 deletions config/locales/models/invitations.pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,26 @@ pt-BR:
invitations:
create:
success: Convite enviado com sucesso!
fail: Prazo de validade não pode ser negativo
fail: Não foi possível convidar o usuário
pending_invitation: Esse usuário possui convite pendente
cancel:
success: Convite cancelado!
fail: Não foi possível cancelar o convite
accept:
success: Parabéns, você agora faz parte deste projeto!
fail: Não foi possível aceitar o convite
decline:
success: Você recusou o convite
fail: Não foi possível recusar o convite
expired: Convite expirado
cancelled: Convite cancelado
accepted: Convite aceito
declined: Convite recusado
accept_btn: Aceitar
decline_btn: Recusar
send_invitation: Enviar convite
pending_invitation: Esse usuário possui convite pendente
cancel_button: Cancelar convite
cancel_button: Cancelar convite
empty_state: Não há convites registrados
already_member: Este usuário já faz parte do projeto.
no_expiration_date: Sem prazo de validade
5 changes: 5 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
end
end

resources :invitations, only: %i[index show] do
patch 'accept', on: :member
patch 'decline', on: :member
end

resources :tasks, only: %i[show edit update] do
member do
post 'start'
Expand Down
11 changes: 11 additions & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
category: 'Secreta')
encrenca_project.user_roles.create!([{ user: jessie, role: :admin }])

ash_project = FactoryBot.create(:project, user: ash, title: 'Pousadaria', category: 'Aplicação WEB')
ash_project2 = FactoryBot.create(:project, user: ash, title: 'Portfoliorr', category: 'Aplicação WEB')
pokemon_project = FactoryBot.create(:project, user: brock, title: 'Líder de Ginásio',
description: 'Me tornar líder do estádio de pedra.',
category: 'Auto Ajuda')


FactoryBot.create(:task, project: pokemon_project, title:'Pegar um geodude',
Expand Down Expand Up @@ -112,3 +117,9 @@
FactoryBot.create(:meeting, project: pokemon_project, user_role: UserRole.find_by(user: brock, project: pokemon_project),
title:'Daily', description:'', datetime: 5.days.from_now, duration: 15,
address: 'https://meet.google.com/')

FactoryBot.create(:invitation, project: ash_project, profile_email: brock.email,
message: 'Adoraria que fizesse parte da minha equipe')

FactoryBot.create(:invitation, project: ash_project2, profile_email: brock.email,
expiration_days: '')
Loading

0 comments on commit a505be8

Please sign in to comment.