criando users

This commit is contained in:
Lucas Rodrigues 2025-10-10 20:04:48 -03:00
parent 612a70ee90
commit 1b477c10f0
2 changed files with 221 additions and 185 deletions

View File

@ -3,60 +3,57 @@
import { useState } from "react"
import { useRouter } from "next/navigation"
import Link from "next/link"
import { Button } from "components/ui/button"
import { Input } from "components/ui/input"
import { Label } from "components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "components/ui/select"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Save, Loader2 } from "lucide-react"
import ManagerLayout from "components/manager-layout"
import ManagerLayout from "@/components/manager-layout"
import { usersService } from "services/usersApi.mjs";
interface UserFormData {
email: string;
password: string;
nomeCompleto: string;
telefone: string;
cargo: string;
papel: string;
}
const defaultFormData: UserFormData = {
email: '',
password: '',
nomeCompleto: '',
telefone: '',
cargo: '',
papel: '',
};
// Remove todos os caracteres não numéricos
const cleanNumber = (value: string): string => value.replace(/\D/g, '');
// Definição do requisito mínimo de senha
const MIN_PASSWORD_LENGTH = 8;
const formatPhone = (value: string): string => {
const cleaned = cleanNumber(value).substring(0, 11);
if (cleaned.length === 11) {
return cleaned.replace(/(\d{2})(\d{5})(\d{4})/, '($1) $2-$3');
}
if (cleaned.length === 10) {
return cleaned.replace(/(\d{2})(\d{4})(\d{4})/, '($1) $2-$3');
}
return cleaned;
};
export default function NovoUsuarioPage() {
const router = useRouter();
const [formData, setFormData] = useState<UserFormData>(defaultFormData);
const [isSaving, setIsSaving] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleInputChange = (key: keyof UserFormData, value: string) => {
const updatedValue = key === 'telefone' ? formatPhone(value) : value;
setFormData((prev) => ({ ...prev, [key]: updatedValue }));
@ -68,28 +65,49 @@ export default function NovoUsuarioPage() {
setError(null);
// Basic validation
if (!formData.email || !formData.password || !formData.nomeCompleto || !formData.cargo) {
if (!formData.email || !formData.password || !formData.nomeCompleto || !formData.papel) {
setError("Por favor, preencha todos os campos obrigatórios.");
return;
}
// Validação de comprimento mínimo da senha
if (formData.password.length < MIN_PASSWORD_LENGTH) {
setError(`A senha deve ter no mínimo ${MIN_PASSWORD_LENGTH} caracteres.`);
return;
}
setIsSaving(true);
// Prepare payload for the API
const payload = {
// ----------------------------------------------------------------------
// CORREÇÃO FINAL: Usa o formato de telefone que o mock API comprovadamente aceitou.
// ----------------------------------------------------------------------
const phoneValue = formData.telefone.trim();
// Prepara o payload com os campos obrigatórios
const payload: any = {
email: formData.email,
password: formData.password,
full_name: formData.nomeCompleto,
phone: formData.telefone.trim() || null,
role: formData.cargo,
role: formData.papel,
};
// Adiciona o telefone APENAS se estiver preenchido, enviando o formato FORMATADO.
if (phoneValue.length > 0) {
payload.phone = phoneValue;
}
// ----------------------------------------------------------------------
try {
await usersService.create_user(payload);
router.push("/manager/usuario");
} catch (e: any) {
console.error("Erro ao criar usuário:", e);
setError(e.message || "Ocorreu um erro inesperado. Tente novamente.");
// Melhorando a mensagem de erro para o usuário final
const apiErrorMsg = e.message?.includes("500")
? "Erro interno do servidor. Verifique os logs do backend ou tente novamente mais tarde. (Possível problema: E-mail já em uso ou falha de conexão.)"
: e.message || "Ocorreu um erro inesperado. Tente novamente.";
setError(apiErrorMsg);
} finally {
setIsSaving(false);
}
@ -153,7 +171,10 @@ export default function NovoUsuarioPage() {
onChange={(e) => handleInputChange("password", e.target.value)}
placeholder="••••••••"
required
minLength={MIN_PASSWORD_LENGTH} // Adiciona validação HTML
/>
{/* MENSAGEM DE AJUDA PARA SENHA */}
<p className="text-xs text-gray-500">Mínimo de {MIN_PASSWORD_LENGTH} caracteres.</p>
</div>
</div>
@ -170,7 +191,7 @@ export default function NovoUsuarioPage() {
</div>
<div className="space-y-2">
<Label htmlFor="papel">Papel (Função) *</Label>
<Select value={formData.cargo} onValueChange={(v) => handleInputChange("cargo", v)} required>
<Select value={formData.papel} onValueChange={(v) => handleInputChange("papel", v)} required>
<SelectTrigger id="papel">
<SelectValue placeholder="Selecione uma função" />
</SelectTrigger>

View File

@ -1,8 +1,23 @@
// services/usersApi.mjs (Versão Corrigida)
import { api } from "./api.mjs";
export const usersService = {
create_user: (data) => api.post(`/functions/v1/create-user`),
list_roles: () => api.get(`/rest/v1/user_roles`),
full_data: (id) => api.get(`/functions/v1/user-info?user_id=${id}`),
// CORREÇÃO: Voltamos a pedir apenas os campos que sabemos que a view 'user_roles' tem
// (id ou user_id, e role), e usamos o endpoint 'full_data' para obter os detalhes de nome/telefone.
// SE a sua view 'user_roles' contiver uma coluna chamada 'user_id', tente a próxima linha:
// list_roles: () => api.get(`/rest/v1/user_roles?select=user_id,role,profiles(full_name,phone)`),
//
// PORÉM, VAMOS ASSUMIR QUE A RELAÇÃO ESTÁ REALMENTE QUEBRADA E SIMPLIFICAR A CHAMADA INICIAL:
list_roles: () => api.get(`/rest/v1/user_roles?select=id,user_id,email,role`),
// Se o email também não estiver em 'user_roles', apenas use 'id,user_id,role'.
// O importante é que esta chamada de API NÃO DÊ ERRO 400.
full_data: (id) => {
const endpoint = `/functions/v1/user-info?user_id=${id}`;
return api.get(endpoint);
},
summary_data: () => api.get(`/auth/v1/user`)
}