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

Adiciona interação por comentários em publicações no Fórum #129

Merged
merged 19 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
90c72cf
WIP: Usuario visualiza comentario
MoisesssDev Feb 13, 2024
69e500a
Insere variavel de comentarios ao controller
MoisesssDev Feb 13, 2024
c0b1dbb
Adiciona exibição de comentários
valerialrc Feb 13, 2024
ae4881f
Refatora forúm e adiciona novos cenários de teste
valerialrc Feb 14, 2024
e253232
Adiciona formulário para criação de comentários
valerialrc Feb 14, 2024
5d68fa9
Adiciona teste para criação de comentário
valerialrc Feb 14, 2024
cfc3d9f
Adiciona lógica para a criação do comentário
MoisesssDev Feb 15, 2024
6b7d6d5
Adiciona uma resposta json ao controller e formatação da data do come…
MoisesssDev Feb 15, 2024
f0aab7a
Adiciona testes de requisição e validação para campo vazio
MoisesssDev Feb 15, 2024
4018d31
adiciona testes unitarios
MoisesssDev Feb 15, 2024
ede2f93
Refatorando a rota para API, adicionando novo cenario no teste de sis…
MoisesssDev Feb 15, 2024
c3e3ff4
Adicionando traduções na view
MoisesssDev Feb 15, 2024
b04dbb8
Remove metodo inutilizado
MoisesssDev Feb 15, 2024
a91871c
Adiciona novo seed
MoisesssDev Feb 15, 2024
5e8bacf
Merge branch 'main' into feature/usuario-comenta-postagem
valerialrc Feb 15, 2024
47ba932
Passando a logica da data formatada para o controller
MoisesssDev Feb 16, 2024
017151a
Merge branch 'main' into feature/usuario-comenta-postagem
MoisesssDev Feb 16, 2024
d436a07
Merge branch 'feature/usuario-comenta-postagem' of github.com:TreinaD…
MoisesssDev Feb 16, 2024
d8924db
Merge branch 'main' into feature/usuario-comenta-postagem
valerialrc Feb 16, 2024
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
39 changes: 39 additions & 0 deletions app/controllers/api/v1/comments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Api
module V1
class CommentsController < Api::V1::ApiController
before_action :authenticate_user!
before_action :set_post, only: %i[create]
before_action :authorize_member, only: %i[create]

def create
@comment = @post.comments.build(comment_params)
@comment.user_role = UserRole.find_by(user: current_user, project: @post.project)

return render status: :created, json: json_response(@comment) if @comment.save

render status: :unprocessable_entity, json: { errors: @comment.errors.full_messages }
end

private

def json_response(comment)
{ id: comment.id, content: comment.content, author: comment.user_role.user.full_name,
created_at: comment.formatted_date }
end

def comment_params
params.require(:comment).permit(:content)
end

def authorize_member
return if @post.project.member? current_user

render status: :unauthorized, json: { errors: I18n.t('unauthorized') }
end

def set_post
@post = Post.find(params[:post_id])
end
end
end
end
6 changes: 6 additions & 0 deletions app/controllers/forums_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ForumsController < ApplicationController
def index
@project = Project.find(params[:project_id])
@posts = @project.posts
end
end
4 changes: 2 additions & 2 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
import "@hotwired/turbo-rails"
import * as bootstrap from "bootstrap"
import { createApp } from 'vue/dist/vue.esm-bundler.js'
import HelloComponent from './components/hello_vue.js'
import ForumComponent from './components/forum_vue.js'

createApp(HelloComponent).mount('#vue-app')
createApp(ForumComponent).mount('#vue-app')
85 changes: 85 additions & 0 deletions app/javascript/components/forum_vue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { ref } from "vue/dist/vue.esm-bundler.js"

export default {
data() {
return {
searchText: '',
selectedFilter: '',
selectedPost: '',
project: window.project,
posts: [],
comments: [],
activePage: 'postsIndex',
newComment: {
content: ''
},
errorMessages: ''
}
},

mounted() {
this.loadPosts();
},

computed:{
filteredPosts() {
const searchType = this.selectedFilter
return this.posts.filter(post => {
if (searchType === '') {
return (
post.title.toLowerCase().includes(this.searchText.toLowerCase()) ||
post.body.toLowerCase().includes(this.searchText.toLowerCase())
)
} else {
return post[searchType].toLowerCase().includes(this.searchText.toLowerCase());
}
})
}
},

methods: {
loadPosts(){
this.posts = window.posts.map(item => ({ id: item.id,
title: item.title,
body: item.body,
author: item.user_name,
date: item.created_at,
comments: item.comments }));

this.activePage = 'postsIndex'
},

showPostDetails(id) {
this.selectedPost = this.posts.find(post => post.id === id);

this.comments = this.selectedPost.comments

this.activePage = 'postDetails'
},

async createComment() {
this.errorMessages = ''

const response = await fetch(`/api/v1/posts/${this.selectedPost.id}/comments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ comment: this.newComment })
})

const data = await response.json()
console.log(data.errors)

if (!response.ok) {
return this.errorMessages = data.errors
}

this.comments.push(data)

this.newComment = {
content: ''
}
},
}
}
3 changes: 2 additions & 1 deletion app/javascript/components/hello_vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export default {
data() {
return {
message: 'Hello!',
insertText: ''
insertText: '',
project: 'Hello Projects'
}
},

Expand Down
13 changes: 13 additions & 0 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'action_view'

class Comment < ApplicationRecord
validates :content, presence: true
include ActionView::Helpers::DateHelper

belongs_to :post
belongs_to :user_role

def formatted_date
valerialrc marked this conversation as resolved.
Show resolved Hide resolved
"Postado há #{time_ago_in_words(created_at)}"
end
valerialrc marked this conversation as resolved.
Show resolved Hide resolved
end
6 changes: 6 additions & 0 deletions app/models/post.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Post < ApplicationRecord
belongs_to :user_role
belongs_to :project
has_many :comments, dependent: :destroy
delegate :user, to: :user_role
end
1 change: 1 addition & 0 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Project < ApplicationRecord
has_many :meetings, dependent: :destroy
has_many :project_job_categories, dependent: :destroy
has_many :proposals, dependent: :destroy
has_many :posts, dependent: :destroy

validates :title, :description, :category, presence: true

Expand Down
1 change: 1 addition & 0 deletions app/models/user_role.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class UserRole < ApplicationRecord
belongs_to :project
has_many :meeting_participants, dependent: :destroy
has_many :meetings, through: :meeting_participants
has_many :comments, dependent: :destroy

enum role: { contributor: 1, admin: 5, leader: 9 }

Expand Down
77 changes: 77 additions & 0 deletions app/views/forums/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<%= render 'shared/project_header', project: @project %>
<div id="vue-app">
<forum-vue>
<div class="row">
<div v-if="activePage === 'postsIndex'" class="col-md-8 mx-auto mt-3">
<label class="form-label visually-hidden" for="searchText">Pesquisar</label>
<input class="form-control mb-3" v-model="searchText" type="text" name="searchText" id="searchText" placeholder="Busque por postagens">

<div class="list-group">
<div class="list-group-item" v-for="post in filteredPosts" :key="post.id">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"><a href="#" @click.prevent="showPostDetails(post.id)"> {{ post.title }}</a></h5>
<small>{{ post.date }}</small>
</div>
<p class="mb-1">{{ post.body }}</p>
<small>por {{ post.author }}</small>
</div>
</div>
</div>

<div v-if="activePage === 'postDetails'">
<div>
<h3>{{ selectedPost.title }}</h3>
<p>{{ selectedPost.body }}</p>
</div>

<div class="list-group">
<p><%= t(Comment.model_name.human(count: 2))%>:</p>
<div class="list-group-item" v-if="comments.length > 0" v-for="comment in comments" :key="comment.id">
<div class="d-flex w-100 justify-content-between">
<p class="mb-1">{{ comment.content }}</p>

<small>{{ comment.created_at }}</small>
</div>
<small>por {{ comment.author }}</small>
</div>
<div v-else>
<p><%= t('comments.first') %></p>
</div>
<form @submit.prevent='createComment' class="mt-4">
<div>
<label for="content" class="d-none"><%= Comment.human_attribute_name :content %>:</label>
<textarea id="content" v-model="newComment.content" placeholder="<%= t('comments.comment_placeholder') %>" class="form-control"></textarea>
<div v-if="errorMessages.length > 0" v-for="msg in errorMessages">
<small class="text-danger">{{ msg }}</small>
</div>
</div>
<div>
<button type="submit" class="btn btn-primary mt-3"><%= t('comments.comment_btn')%></button>
</div>
</form>
<div>
<button class='btn btn-outline-primary mt-3' @click="loadPosts"><%= t('back')%></button>
</div>
</div>
</div>
</div>
</forum-vue>
</div>

<script>
var project = "<%= @project.title %>"
var posts = <%= @posts.map { |post| { id: post.id,
title: post.title,
body: post.body,
comments: post.comments.map { |comment|
{
id: comment.id,
content: comment.content,
author: comment.user_role.user.full_name,
created_at: comment.updated_at == comment.created_at ? "Postado há #{time_ago_in_words(comment.created_at)}" : "(Editado) #{time_ago_in_words(comment.updated_at)}",
}
},
created_at: post.updated_at == post.created_at ? "Postado em #{time_ago_in_words(post.created_at)}" : "(Editado) #{time_ago_in_words(post.updated_at)}",
user_name: post.user.full_name } }.to_json.html_safe %>;

</script>
5 changes: 5 additions & 0 deletions app/views/shared/_project_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
class: "nav-item nav-link link-body-emphasis
#{'active' if request.path.include?('/members') ||
request.path.include?('/user_roles') }" %>
<%= link_to t('forum.title'),
project_forum_path(project),
class: "nav-item nav-link link-body-emphasis
#{'active' if request.path.include?('/forum')}",
data: { turbo: false } %>
<% if project.leader?(current_user) %>
<%= link_to t(:search_users_btn),
search_project_portfoliorrr_profiles_path(project),
Expand Down
3 changes: 3 additions & 0 deletions config/locales/forum.pt-BR.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pt-BR:
forum:
title: Fórum
15 changes: 15 additions & 0 deletions config/locales/models/comments.pt-BR.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pt-BR:
activerecord:
models:
comment:
one: Comentário
other: Comentários
attributes:
comment:
content: Conteúdo
user_role_id: Autor
post_id: Publicação
comments:
comment_btn: Comentar
comment_placeholder: Insira um comentário
first: Seja o primeiro a comentar
6 changes: 6 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
resources :user_roles, only: %i[edit update]
resources :proposals, only: %i[index]
resources :calendars, only: %i[index]

get 'forum', to: 'forums#index'

resources :invitations, only: %i[index], to: 'projects#invitations'
end

Expand Down Expand Up @@ -58,6 +61,9 @@
resources :projects, only: %i[index]
resources :invitations, only: %i[index update]
resources :proposals, only: %i[create update]
resources :posts, only: %i[] do
resources :comments, only: %i[create]
end
end
end
end
12 changes: 12 additions & 0 deletions db/migrate/20240212192630_create_posts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreatePosts < ActiveRecord::Migration[7.1]
def change
create_table :posts do |t|
t.string :title
t.string :body
t.references :user_role, null: false, foreign_key: true
t.references :project, null: false, foreign_key: true

t.timestamps
end
end
end
11 changes: 11 additions & 0 deletions db/migrate/20240213182535_create_comments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateComments < ActiveRecord::Migration[7.1]
def change
create_table :comments do |t|
t.text :content
t.references :post, null: false, foreign_key: true
t.references :user_role, null: false, foreign_key: true

t.timestamps
end
end
end
Loading
Loading