<!
DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cadastro da Empresa</title>
<link href="[Link]
rel="stylesheet">
<style>
body {
background-color: #00d0ff;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
#card {
background: white;
padding: 30px;
border-radius: 12px;
width: 100%;
max-width: 420px;
box-shadow: 0 10px 20px rgba(0,0,0,0.3);
h1 {
text-align: center;
color: #00d0ff;
margin-bottom: 20px;
</style>
</head>
<body>
<div id="card">
<h1>Cadastrar Empresa</h1>
<form id="cadastroEmpresaForm">
<input type="text" id="nomeEmpresa" class="form-control mb-3" placeholder="Nome da
Empresa">
<input type="text" id="nif" class="form-control mb-3" placeholder="NIF">
<input type="text" id="endereco" class="form-control mb-3" placeholder="Endereço">
<!-- 🔥 CORRIGIDO -->
<select id="areaAtuacao" class="form-select mb-3">
<option value="" disabled selected>Selecione a área</option>
<option value="Desenhador_Projetista">Desenhador Projetista</option>
<option value="Eletricidade">Eletricidade</option>
<option value="Frio_Climatizacao">Frio e Climatização</option>
<option value="Gestao_Sistemas_Informaticos">Gestão de Sistemas Informáticos</option>
<option value="Informatica">Informática</option>
<option value="Obras_Construcao_Civil">Obras de Construção Civil</option>
<option value="Tecnologia_Moveis">Tecnologia de Móveis</option>
</select>
<input type="email" id="email" class="form-control mb-3" placeholder="Email">
<input type="text" id="telefone" class="form-control mb-3" placeholder="Telefone">
<input type="password" id="senha" class="form-control mb-3" placeholder="Senha">
<button type="submit" class="btn btn-primary w-100">Cadastrar</button>
<div class="text-center mt-3">
<p>Já tem conta? <a href="[Link]">Entrar</a></p>
</div>
</form>
</div>
<script>
const API_URL = "[Link]
[Link]("cadastroEmpresaForm").addEventListener("submit", async
function(e) {
[Link]();
const payload = {
nomeEmpresa: [Link]("nomeEmpresa").[Link](),
nif: [Link]("nif").[Link](),
endereco: [Link]("endereco").[Link](),
areaAtuacao: [Link]("areaAtuacao").value,
email: [Link]("email").[Link](),
telefone: [Link]("telefone").[Link](),
senha: [Link]("senha").[Link]()
};
[Link]("📤 Enviando:", payload);
// 🔥 VALIDAÇÃO FRONT (evita erro do enum)
if (![Link]) {
alert("Selecione a área de atuação");
return;
try {
const response = await fetch(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: [Link](payload)
});
let data = null;
try {
data = await [Link]();
} catch {
[Link]("Resposta sem JSON");
[Link]("📥 Resposta:", data);
// ❌ ERRO
if (![Link]) {
// 🔴 VALIDAÇÃO (DTO)
if (data && [Link]) {
let msg = "";
for (const campo in [Link]) {
msg += `• ${campo}: ${[Link][campo]}\n`;
alert(msg);
// 🔴 ERRO DE NEGÓCIO (service)
else if (data && [Link]) {
alert([Link]);
// 🔴 QUALQUER OUTRO
else {
alert("Erro ao cadastrar. Ver console.");
return;
// ✅ SUCESSO
alert("Empresa cadastrada com sucesso!");
[Link]("cadastroEmpresaForm").reset();
[Link] = "[Link]";
} catch (error) {
[Link]("❌ ERRO:", error);
alert("Erro de conexão com o servidor");
});
</script>
</body>
</html>
Agora sim — esse erro está claríssimo e 100% identificado:
❌ ERRO REAL
Cannot deserialize value of type AreaAtuacao from String "Área de
atuação"
👉 Ou seja:
O backend está recebendo isto:
"areaAtuacao": "Área de atuação"
E isso NÃO é um valor válido do enum.
🎯 CAUSA EXATA
No teu HTML:
<option disabled selected>Área de atuação</option>
👉 Esse option não tem value, então o browser envia exatamente o texto:
"Área de atuação"
E o Java espera:
Eletricidade
Informatica
Frio_Climatizacao
...
✅ CORREÇÃO (OBRIGATÓRIA)
🔥 MUDA O SELECT PARA ISSO:
<select id="areaAtuacao" class="form-select mb-3" required>
<option value="" disabled selected>Selecione a área</option>
<option value="Desenhador_Projetista">Desenhador Projetista</option>
<option value="Eletricidade">Eletricidade</option>
<option value="Frio_Climatizacao">Frio e Climatização</option>
<option value="Gestao_Sistemas_Informáticos">Gestão de Sistemas
Informáticos</option>
<option value="Informatica">Informática</option>
<option value="Obras_Construção_Civil">Obras de Construção
Civil</option>
<option value="Tecnologia_Móveis">Tecnologia de Móveis</option>
</select>
✅ 🔥 VALIDAÇÃO NO FRONT (EVITAR
ERRO ANTES DE ENVIAR)
Adiciona isso antes de enviar:
const area = [Link]("areaAtuacao").value;
if (!area) {
alert("Selecione a área de atuação");
return;
}
⚠️OUTRO POSSÍVEL ERRO
(IMPORTANTE)
Enums com acentos podem dar problema dependendo do Jackson.
👉 Exemplo:
Tecnologia_Móveis
Gestao_Sistemas_Informáticos
💥 Isso é arriscado.
🔥 MELHOR PRÁTICA
(RECOMENDADO)
No Java enum, usa SEM acento:
Tecnologia_Moveis,
Gestao_Sistemas_Informaticos
E no HTML:
<option value="Tecnologia_Moveis">Tecnologia de Móveis</option>
<option value="Gestao_Sistemas_Informaticos">Gestão de Sistemas
Informáticos</option>
👉 Texto pode ter acento
👉 value NÃO deve ter
✅ RESUMO FINAL
✔ Erro NÃO é backend
✔ Erro NÃO é DTO
✔ Erro NÃO é JSON geral
👉 Erro é 100% no <select>
🚀 RESULTADO DEPOIS DA
CORREÇÃO
✔ Enum vai casar corretamente
✔ JSON válido
✔ Cadastro funciona
✔ Sem erro de parse
Se quiser, próximo passo:
👉 validar TODOS os campos no front igual sistema profissional
👉 destacar campo com erro (tipo vermelho)
👉 UX nível sistema real
Só dizer 👍
Perfeito — agora vamos ligar backend → frontend → redirecionamento por tipo de
usuário de forma correta e sem erro.
👉 O teu backend já devolve isto no login:
{
"idUsuario": "...",
"email": "...",
"telefone": "...",
"tipoUsuario": "ESTUDANTE",
"mensagem": "LOGIN OK"
}
Então o frontend só precisa:
1. Ler tipoUsuario
2. Redirecionar conforme o tipo
3. Guardar dados (opcional, mas recomendado)
✅ 🔥 LOGIN FRONT CORRIGIDO
(COM REDIRECIONAMENTO)
👉 Substitui APENAS O <script> do login por este:
<script>
const API_URL = "[Link]
[Link]("loginForm").addEventListener("submit", async
function(e) {
[Link]();
const loginInput = [Link]("login").[Link]();
const senha = [Link]("password").[Link]();
const payload = { email: null, telefone: null, senha: senha };
// 🔥 DEFINE SE É EMAIL OU TELEFONE
if ([Link]("@")) {
[Link] = loginInput;
} else {
[Link] = loginInput;
}
try {
const response = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: [Link](payload)
});
let data = null;
try { data = await [Link](); } catch {}
[Link]("RESPOSTA:", data);
// ❌ ERRO
if (![Link] || [Link] !== "LOGIN OK") {
alert(data?.mensagem || "Erro ao fazer login");
return;
}
// ✅ GUARDAR DADOS DO USUÁRIO (IMPORTANTE)
[Link]("usuario", [Link](data));
alert("Login feito com sucesso!");
// 🔥 REDIRECIONAMENTO POR TIPO
switch ([Link]) {
case "ESTUDANTE":
[Link] = "[Link]";
break;
case "EMPRESA":
[Link] = "[Link]";
break;
case "ORIENTADOR":
[Link] = "[Link]";
break;
case "ADMINISTRADOR":
[Link] = "[Link]";
break;
case "SUPERVISOR":
[Link] = "[Link]";
break;
default:
alert("Tipo de usuário desconhecido");
}
} catch (error) {
[Link](error);
alert("Erro de conexão com o servidor.");
}
});
</script>
⚠️🔴 ATENÇÃO AOS LINKS (ERRO
QUE VOCÊ IA TER)
Você tem nomes diferentes:
Tipo Página
ESTUDANTE [Link]
EMPRESA [Link] ⚠️(extensão diferente)
ORIENTADOR [Link]
ADMIN [Link]
SUPERVISOR [Link]
👉 Se errar UMA letra → não abre página
✅ 🔥 MELHOR PRÁTICA
(RECOMENDADO)
Padroniza nomes assim:
[Link]
[Link]
[Link]
[Link]
[Link]
E muda o switch para:
case "ESTUDANTE":
[Link] = "[Link]";
break;
case "EMPRESA":
[Link] = "[Link]";
break;
case "ORIENTADOR":
[Link] = "[Link]";
break;
case "ADMINISTRADOR":
[Link] = "[Link]";
break;
case "SUPERVISOR":
[Link] = "[Link]";
break;
✅ 🔥 EXTRA (IMPORTANTE MESMO)
Se quiser usar os dados depois:
const usuario = [Link]([Link]("usuario"));
[Link]([Link]);
[Link]([Link]);
🎯 RESULTADO FINAL
✔ Login funciona
✔ Sem erro
✔ Redireciona certo
✔ Backend integrado
✔ Front organizado
🚨 SE NÃO REDIRECIONAR
Verifica:
1. Nome do arquivo errado
2. Caminho errado (../ etc)
3. Backend não está retornando tipoUsuario
Se quiser, próximo passo:
👉 proteger páginas (não entrar sem login)
👉 logout real
👉 sessão tipo sistema profissional
Só dizer.