270 lines
7.6 KiB
Markdown
270 lines
7.6 KiB
Markdown
# APRENDIZADOS TÉCNICOS - WEBMONEY
|
|
|
|
Este documento registra problemas encontrados e suas soluções para referência futura.
|
|
|
|
---
|
|
|
|
## 📋 Índice
|
|
|
|
1. [Bootstrap 5 + React: Componentes JS não funcionam](#1-bootstrap-5--react-componentes-js-não-funcionam)
|
|
2. [Deploy: Arquivos no diretório errado](#2-deploy-arquivos-no-diretório-errado)
|
|
|
|
---
|
|
|
|
## 1. Bootstrap 5 + React: Componentes JS não funcionam
|
|
|
|
**Data:** 8 de Dezembro de 2025
|
|
**Versões afetadas:** v1.3.8 - v1.3.11
|
|
**Componentes afetados:** Dropdown, Modal
|
|
|
|
### ❌ Problema
|
|
|
|
Componentes do Bootstrap 5 que dependem de JavaScript (Dropdown, Modal, Tooltip, Popover, etc.) **não funcionam** corretamente em aplicações React, mesmo importando o Bootstrap JS.
|
|
|
|
**Sintomas:**
|
|
- Dropdown não abre ao clicar
|
|
- Modal não aparece
|
|
- `data-bs-toggle="dropdown"` não faz nada
|
|
- `window.bootstrap.Modal` não inicializa corretamente
|
|
|
|
### 🔍 Causa Raiz
|
|
|
|
O Bootstrap 5 JavaScript foi projetado para manipular o DOM diretamente, o que conflita com o Virtual DOM do React:
|
|
|
|
1. **Ciclo de vida:** Bootstrap inicializa componentes no `DOMContentLoaded`, mas React renderiza depois
|
|
2. **Re-renders:** Quando React re-renderiza, os listeners do Bootstrap são perdidos
|
|
3. **Referências:** `new bootstrap.Modal(element)` pode referenciar elementos que React já substituiu
|
|
|
|
### ✅ Solução
|
|
|
|
**Implementar os componentes usando 100% React puro**, sem depender da API JavaScript do Bootstrap.
|
|
|
|
#### Dropdown Controlado (React)
|
|
|
|
```jsx
|
|
// ❌ ERRADO - Não funciona
|
|
<div className="dropdown">
|
|
<button data-bs-toggle="dropdown">Menu</button>
|
|
<ul className="dropdown-menu">...</ul>
|
|
</div>
|
|
|
|
// ✅ CORRETO - React controlado
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const dropdownRef = useRef(null);
|
|
|
|
// Fechar ao clicar fora
|
|
useEffect(() => {
|
|
const handleClickOutside = (e) => {
|
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
setIsOpen(false);
|
|
}
|
|
};
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
}, []);
|
|
|
|
<div className="dropdown" ref={dropdownRef} style={{ position: 'relative' }}>
|
|
<button onClick={() => setIsOpen(!isOpen)}>Menu</button>
|
|
<ul
|
|
className={`dropdown-menu ${isOpen ? 'show' : ''}`}
|
|
style={{
|
|
position: 'absolute',
|
|
right: 0,
|
|
top: '100%',
|
|
zIndex: 1000
|
|
}}
|
|
>
|
|
...
|
|
</ul>
|
|
</div>
|
|
```
|
|
|
|
#### Modal Controlado (React)
|
|
|
|
```jsx
|
|
// ❌ ERRADO - Depende de window.bootstrap
|
|
useEffect(() => {
|
|
if (window.bootstrap) {
|
|
const modal = new window.bootstrap.Modal(modalRef.current);
|
|
// Não funciona consistentemente
|
|
}
|
|
}, []);
|
|
|
|
// ✅ CORRETO - React puro
|
|
const Modal = ({ show, onHide, title, children, footer }) => {
|
|
// Fechar com ESC
|
|
useEffect(() => {
|
|
const handleKeyDown = (e) => {
|
|
if (e.key === 'Escape' && show) onHide();
|
|
};
|
|
if (show) {
|
|
document.addEventListener('keydown', handleKeyDown);
|
|
document.body.style.overflow = 'hidden'; // Bloqueia scroll
|
|
}
|
|
return () => {
|
|
document.removeEventListener('keydown', handleKeyDown);
|
|
document.body.style.overflow = '';
|
|
};
|
|
}, [show, onHide]);
|
|
|
|
if (!show) return null;
|
|
|
|
return (
|
|
<>
|
|
<div className="modal-backdrop show" style={{ backgroundColor: 'rgba(0,0,0,0.7)' }} />
|
|
<div className="modal show d-block" onClick={(e) => e.target === e.currentTarget && onHide()}>
|
|
<div className="modal-dialog modal-dialog-centered">
|
|
<div className="modal-content">
|
|
<div className="modal-header">
|
|
<h5>{title}</h5>
|
|
<button className="btn-close" onClick={onHide} />
|
|
</div>
|
|
<div className="modal-body">{children}</div>
|
|
{footer && <div className="modal-footer">{footer}</div>}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
```
|
|
|
|
### 📝 Regra para o Futuro
|
|
|
|
> **NUNCA usar `data-bs-toggle`, `data-bs-dismiss` ou `window.bootstrap` em React.**
|
|
>
|
|
> Sempre implementar componentes interativos com `useState`, `useRef` e `useEffect`.
|
|
|
|
### 🔗 Alternativas
|
|
|
|
Se precisar de muitos componentes Bootstrap interativos, considere usar:
|
|
- **React-Bootstrap** (https://react-bootstrap.github.io/)
|
|
- **Reactstrap** (https://reactstrap.github.io/)
|
|
|
|
Estas bibliotecas reimplementam os componentes Bootstrap em React puro.
|
|
|
|
---
|
|
|
|
## 2. Deploy: Arquivos no diretório errado
|
|
|
|
**Data:** 8 de Dezembro de 2025
|
|
**Versão afetada:** v1.3.10
|
|
|
|
### ❌ Problema
|
|
|
|
Após fazer deploy do frontend, o site retornava **404** ou **403 Forbidden**.
|
|
|
|
**Sintomas:**
|
|
- `curl https://webmoney.cnxifly.com/` retorna 404/403
|
|
- Arquivos existem no servidor mas não são servidos
|
|
- JS/CSS não carregam
|
|
|
|
### 🔍 Causa Raiz
|
|
|
|
Os arquivos foram copiados para o diretório **errado**:
|
|
|
|
```
|
|
# Onde os arquivos foram copiados:
|
|
/var/www/webmoney/frontend/assets/
|
|
|
|
# Onde o Nginx esperava encontrar:
|
|
/var/www/webmoney/frontend/dist/assets/
|
|
```
|
|
|
|
O Nginx estava configurado com:
|
|
```nginx
|
|
root /var/www/webmoney/frontend/dist;
|
|
```
|
|
|
|
### ✅ Solução
|
|
|
|
1. **Verificar configuração do Nginx:**
|
|
```bash
|
|
cat /etc/nginx/sites-available/webmoney-subdomain
|
|
# Procurar por: root /var/www/webmoney/frontend/dist;
|
|
```
|
|
|
|
2. **Deploy para o caminho correto:**
|
|
```bash
|
|
# Build do frontend
|
|
cd frontend && npm run build
|
|
|
|
# Deploy para o caminho CORRETO (inclui /dist/)
|
|
scp -r dist/* root@213.165.93.60:/var/www/webmoney/frontend/dist/
|
|
```
|
|
|
|
3. **Ajustar permissões:**
|
|
```bash
|
|
chown -R www-data:www-data /var/www/webmoney/frontend/dist
|
|
```
|
|
|
|
### 📝 Regra para o Futuro
|
|
|
|
> **Sempre verificar o `root` do Nginx antes de fazer deploy.**
|
|
>
|
|
> O caminho de deploy deve corresponder EXATAMENTE ao configurado no Nginx.
|
|
|
|
### ✅ Comando de Deploy Correto
|
|
|
|
```bash
|
|
# Frontend - Build e Deploy
|
|
cd /workspaces/webmoney/frontend
|
|
npm run build
|
|
sshpass -p 'Master9354' scp -r dist/* root@213.165.93.60:/var/www/webmoney/frontend/dist/
|
|
|
|
# Backend - Deploy
|
|
sshpass -p 'Master9354' rsync -avz --exclude 'vendor' --exclude '.git' \
|
|
/workspaces/webmoney/backend/ root@213.165.93.60:/var/www/webmoney/backend/
|
|
|
|
# Pós-deploy no servidor
|
|
ssh root@213.165.93.60 "
|
|
cd /var/www/webmoney/backend
|
|
COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader
|
|
cp .env.production .env
|
|
php artisan config:cache
|
|
php artisan route:cache
|
|
chown -R www-data:www-data /var/www/webmoney
|
|
systemctl restart php8.4-fpm
|
|
"
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Resumo de Problemas Frequentes
|
|
|
|
| Problema | Sintoma | Solução Rápida |
|
|
|----------|---------|----------------|
|
|
| Dropdown não abre | Clique não faz nada | Usar `useState` + `onClick` |
|
|
| Modal não aparece | `window.bootstrap` undefined | Implementar modal React puro |
|
|
| 404 no frontend | Site não carrega | Verificar `root` do Nginx |
|
|
| 403 Forbidden | Permissão negada | `chown -R www-data:www-data` |
|
|
| API retorna 404 | Endpoint não encontrado | Verificar se `routes/api.php` foi copiado |
|
|
| Cache desatualizado | Mudanças não aparecem | `php artisan config:clear` + hard refresh |
|
|
|
|
---
|
|
|
|
## 🔧 Checklist de Debug
|
|
|
|
Quando algo não funciona:
|
|
|
|
1. **Frontend não carrega:**
|
|
- [ ] Verificar se `npm run build` foi executado
|
|
- [ ] Verificar se arquivos estão em `/frontend/dist/`
|
|
- [ ] Verificar `root` do Nginx
|
|
- [ ] Fazer hard refresh (Ctrl+Shift+R)
|
|
|
|
2. **Componente React não funciona:**
|
|
- [ ] Verificar se não está usando `data-bs-*`
|
|
- [ ] Verificar console do browser para erros
|
|
- [ ] Implementar com `useState`/`useEffect`
|
|
|
|
3. **API retorna erro:**
|
|
- [ ] Verificar se `routes/api.php` existe no servidor
|
|
- [ ] Verificar se `.env` está configurado
|
|
- [ ] Executar `php artisan config:cache`
|
|
- [ ] Verificar logs: `tail -f /var/log/nginx/webmoney_*.log`
|
|
|
|
---
|
|
|
|
*Documento atualizado em: 8 de Dezembro de 2025 - v1.3.11*
|