Pedido do usuário: "testa arrastando um sub menu pra ver se persiste" — o acordeão da fase anterior só tinha abrir/fechar, nada de arrastar. Perguntei o que ele queria dizer com "arrastar" antes de supor, e a resposta foi: quer a funcionalidade de verdade. @dnd-kit (core + sortable) — cada grupo do menu pode ser arrastado pra reordenar entre si; cada sub-item dentro de um grupo pode ser arrastado pra reordenar DENTRO do próprio grupo (nunca sai pra outro grupo arrastando, checado explicitamente no onDragEnd). Alça de arrastar dedicada (GripVertical) em vez do item inteiro, pra não conflitar com o clique de abrir/fechar acordeão ou navegar pelo link. Ordem salva em localStorage (nav-order.ts), nunca banco — preferência pessoal do navegador, mesma convenção já usada pelo ThemeToggle (claro/escuro/sistema). Uma chave só serve os dois menus (Platform e Tenant), sem colisão de rótulos entre eles. Achado real testando: aplicar a ordem salva direto no inicializador do useState diverge do HTML que o servidor mandou (SSR nunca tem acesso a localStorage) e disparava "Hydration failed" no React — inofensivo no resultado final, mas um erro real no console e uma renderização inteira desperdiçada. Corrigido aplicando a ordem salva só dentro de um useEffect (roda uma vez, só no client) — o mesmo padrão que o ThemeToggle já usava e eu não tinha replicado. Testado com Playwright de verdade em dois cenários: arrastar um grupo inteiro (ordem mudou e sobreviveu a um F5 completo) e arrastar um sub-item dentro de "Discador" (reordenou só ali dentro, confirmado que os outros grupos continuaram intactos, e também sobreviveu ao F5). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
44 lines
1.1 KiB
JSON
44 lines
1.1 KiB
JSON
{
|
|
"name": "@b2bcall/frontend",
|
|
"version": "0.0.1",
|
|
"private": true,
|
|
"scripts": {
|
|
"dev": "next dev",
|
|
"build": "next build",
|
|
"start": "next start",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"@dnd-kit/core": "^6.3.1",
|
|
"@dnd-kit/sortable": "^10.0.0",
|
|
"@dnd-kit/utilities": "^3.2.2",
|
|
"@radix-ui/react-avatar": "1.1.2",
|
|
"@radix-ui/react-dialog": "1.1.4",
|
|
"@radix-ui/react-dropdown-menu": "2.1.4",
|
|
"@radix-ui/react-slot": "1.1.1",
|
|
"@radix-ui/react-tooltip": "1.1.6",
|
|
"@tanstack/react-query": "5.62.7",
|
|
"@tanstack/react-table": "8.20.5",
|
|
"@xyflow/react": "^12.11.5",
|
|
"class-variance-authority": "0.7.1",
|
|
"clsx": "2.1.1",
|
|
"lucide-react": "0.469.0",
|
|
"next": "15.3.9",
|
|
"react": "19.1.0",
|
|
"react-dom": "19.1.0",
|
|
"recharts": "2.15.0",
|
|
"server-only": "0.0.1",
|
|
"socket.io-client": "4.8.3",
|
|
"tailwind-merge": "2.5.5"
|
|
},
|
|
"devDependencies": {
|
|
"@types/node": "^22.20.1",
|
|
"@types/react": "19.1.0",
|
|
"@types/react-dom": "19.1.0",
|
|
"autoprefixer": "10.4.20",
|
|
"postcss": "8.4.49",
|
|
"tailwindcss": "3.4.17",
|
|
"typescript": "^5.7.0"
|
|
}
|
|
}
|