Skip to content

Feat: CRUD de areas no painel do admin#5

Open
GabrielWodtke wants to merge 2 commits into
mainfrom
branch_gabriel
Open

Feat: CRUD de areas no painel do admin#5
GabrielWodtke wants to merge 2 commits into
mainfrom
branch_gabriel

Conversation

@GabrielWodtke
Copy link
Copy Markdown

@GabrielWodtke GabrielWodtke commented Apr 4, 2026

Adicionei um Crud com botões para adicionar areas e remover areas, a aba de remover areas tem um botão de confirmação e ambas ações de deletar ou adicionar só salvam com o botão de "salvar alterações" no painel de admin.
Adicionado Crud de adicionar e remover segmentos de cada área.

@cloudflare-workers-and-pages
Copy link
Copy Markdown
Contributor

cloudflare-workers-and-pages Bot commented Apr 4, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
job-ready-developer 700d572 Commit Preview URL

Branch Preview URL
Apr 07 2026, 01:11 AM

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces functionality to add and remove competency areas within the admin component, including new modals, dropdowns, and associated styles. The review feedback highlights several issues, primarily the use of direct DOM manipulation instead of Angular's declarative patterns, which led to bugs like non-existent element references and potential memory leaks. Other suggestions include adding input validation, removing unused imports and dead code, fixing typos, and preventing runtime errors by disabling buttons when required data is missing.

Comment on lines +706 to +754
const dropbtn = document.getElementById("dropbtn");
const botao_remover = document.getElementById("remover-id-admin");
const modal_dropdown = document.getElementById("modal_dropdown_remove");
botao_remover?.addEventListener("click", () => {
if (modal_dropdown !== null) {
modal_dropdown.style.display = "flex";
}
});

const modal = document.getElementById("modal_admin");
const abrirModal = document.getElementById("abrir-modal-admin");
const fecharModal = document.getElementById("salvar-modal-admin");
const conteudo = document.getElementById("modal_content_admin");

abrirModal?.addEventListener("click", () => {
if (modal !== null) {
modal.style.display = "flex";
}
});

modal?.addEventListener("click", (event) => {
modal.style.display = "none";
});

conteudo?.addEventListener("click", (event) => {
event.stopPropagation();
});

fecharModal?.addEventListener("click", () => {
if (modal !== null) {
modal?.classList.add("inactive");
modal.style.display = "none";
modal?.classList.remove("active");
}
});

const modalDropdown = document.getElementById("modal_dropdown_remove");
const modalDropdownContent = document.getElementById(
"modal_content_dropdown_remove",
);

modalDropdown?.addEventListener("click", (event) => {
if (event.target === modalDropdown) {
modalDropdown.style.display = "none";
}
});
modalDropdownContent?.addEventListener("click", (event) => {
event.stopPropagation();
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

A manipulação direta do DOM usando document.getElementById e addEventListener é um antipadrão em Angular. Isso ignora o ciclo de vida e a detecção de mudanças do Angular, pode levar a memory leaks (os event listeners não são removidos em ngOnDestroy), e torna o componente mais difícil de testar e manter.

Recomendo refatorar este código para usar uma abordagem declarativa do Angular. Por exemplo, você pode usar propriedades no componente para controlar a visibilidade dos modais e aplicar classes ou estilos condicionalmente no template.

Exemplo para o modal de adicionar área:

No componente (.ts):

isAddAreaModalVisible = false;

// ...

openAddAreaModal() {
  this.isAddAreaModalVisible = true;
}

closeAddAreaModal() {
  this.isAddAreaModalVisible = false;
}

No template (.html):

<button (click)="openAddAreaModal()">+ Adicionar Área</button>

<!-- Modal -->
<div class="modal_admin" *ngIf="isAddAreaModalVisible">
  <div class="modal_content_admin">
    <!-- Conteúdo do modal -->
    <button (click)="closeAddAreaModal()">Fechar</button>
  </div>
</div>

Essa abordagem é mais segura, mais limpa e alinhada com as boas práticas do framework.

Comment on lines +151 to +156
<button
class="btn-remove-area"
(click)="removeArea(selectedAreaToRemove()!)"
>
Remover Área
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

A chamada removeArea(selectedAreaToRemove()!) usa o operador de asserção não nula (!). Se o botão for clicado sem que uma área tenha sido selecionada para remoção, selectedAreaToRemove() será null e isso causará um erro em tempo de execução.

Para evitar isso, o botão de remover deve ser desabilitado quando nenhuma área estiver selecionada.

Suggested change
<button
class="btn-remove-area"
(click)="removeArea(selectedAreaToRemove()!)"
>
Remover Área
</button>
<button
class="btn-remove-area"
(click)="removeArea(selectedAreaToRemove()!)"
[disabled]="!selectedAreaToRemove()"
>
Remover Área
</button>


const modal = document.getElementById("modal_admin");
const abrirModal = document.getElementById("abrir-modal-admin");
const fecharModal = document.getElementById("salvar-modal-admin");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

A variável fecharModal está tentando obter um elemento com o ID salvar-modal-admin, mas este ID não existe no template HTML. Como resultado, fecharModal será null e o addEventListener na linha 734 não terá efeito. A lógica para fechar o modal ao salvar uma nova área não está funcionando.

Este problema é um sintoma da manipulação direta do DOM. Ao refatorar para uma abordagem declarativa, como sugerido em outro comentário, este problema será resolvido naturalmente. O método addArea poderia, por exemplo, ser responsável por fechar o modal após a conclusão.

import { CompetencyService } from "../../services/competency.service";
import { Competency, Resource } from "../../models/competency.model";
import { add_new_area } from "../../models/competency.model";
import { doc } from "firebase/firestore";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

O import doc de firebase/firestore não está sendo utilizado neste arquivo e pode ser removido para manter o código limpo.

<input
id="area-desc"
type="text"
placeholder="Brevecd descrição da área"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Há um erro de digitação no texto do placeholder.

Suggested change
placeholder="Brevecd descrição da área"
placeholder="Breve descrição da área"

Comment on lines +765 to +776
dropdown_inactive() {
const myDropdown = document.getElementById("myDropdown");
const modalDropdown = document.getElementsByClassName(
"remove-item-dropdown",
);

modalDropdown[0].addEventListener("click", () => {
if (myDropdown !== null) {
myDropdown.classList.remove("show");
}
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Este método dropdown_inactive não parece ser chamado em nenhum lugar do componente, caracterizando código morto (dead code). Além disso, ele adiciona um event listener de forma insegura (acessando modalDropdown[0]) e sem removê-lo, o que poderia causar memory leaks. Recomendo remover este método.

Comment on lines +778 to +788
addArea(
name: string,
description: string,
color: string,
icon: string,
): void {
if (this.mapRef) {
add_new_area(name, description, color, icon, this.mapRef);
this.areas.set(this.mapRef.children ?? []);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

O método addArea não valida os dados recebidos. Isso permite que um usuário adicione uma nova área com campos vazios, como o nome, o que pode levar a dados inconsistentes.

É uma boa prática validar os inputs antes de processá-los. Adicionalmente, após adicionar uma área com sucesso, os campos do formulário deveriam ser limpos e o modal fechado para melhorar a experiência do usuário.

  addArea(
    name: string,
    description: string,
    color: string,
    icon: string,
  ): void {
    if (!name?.trim()) {
      // Idealmente, notificar o usuário sobre o erro.
      return; 
    }
    if (this.mapRef) {
      add_new_area(name, description, color, icon, this.mapRef);
      this.areas.set(this.mapRef.children ?? []);
      // TODO: Limpar os campos do formulário e fechar o modal aqui.
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant