diff --git a/src/main/webapp/master/clientes.js b/src/main/webapp/master/clientes.js
index 06190bf..60fbc49 100644
--- a/src/main/webapp/master/clientes.js
+++ b/src/main/webapp/master/clientes.js
@@ -16,12 +16,22 @@ function statusAction(e){const acao=e.status==='ativa'?'Bloquear':'Ativar';retur
function detalheRow(e){if(selecionado!==e.id||!modo)return'';if(modo==='ver')return `
${esc(e.nome)}Slug: ${esc(e.slug)} CNPJ: ${esc(e.cnpj||'-')} Status: ${esc(e.status)} Plano: ${e.plano?`${esc(e.plano)} ${e.plano_valor_centavos?'- '+Util.money(e.plano_valor_centavos):''}`:'-'} Conta principal: abra Editar para alterar dados da empresa; funcionarios ficam no acesso da empresa. |
`;return `
|
`}
function proximoSlugSequencial(){
- let max=0;
- for(const e of empresas){
- const n=parseInt(e.slug,10);
- if(!isNaN(n)&&n>max)max=n;
+ const slugsExistentes = new Set(empresas.map(e => String(e.slug || '').trim().toLowerCase()));
+ let max = 0;
+ for (const e of empresas) {
+ const s = String(e.slug || '').trim();
+ const n = parseInt(s, 10);
+ if (!isNaN(n) && /^\d+$/.test(s)) {
+ if (n > max) max = n;
+ }
}
- return String(max+1).padStart(4,'0');
+ let proximo = max + 1;
+ let candidato = String(proximo).padStart(4, '0');
+ while (slugsExistentes.has(candidato.toLowerCase())) {
+ proximo++;
+ candidato = String(proximo).padStart(4, '0');
+ }
+ return candidato;
}
function slugify(text){
@@ -34,6 +44,25 @@ function slugify(text){
.replace(/^_+|_+$/g,'');
}
+function mostrarErroModal(msg){
+ const el = document.querySelector('#modal-error-msg');
+ if(el){
+ el.textContent = msg;
+ el.classList.remove('hidden');
+ el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
+}
+
+function limparErroModal(){
+ const el = document.querySelector('#modal-error-msg');
+ if(el){
+ el.textContent = '';
+ el.classList.add('hidden');
+ }
+ const slugInput = empresaForm.querySelector('input[name="slug"]');
+ if(slugInput) slugInput.style.borderColor = '';
+}
+
function render(){
const q=busca.value.trim();
const lista=empresas.filter(e=>match(e,q));
@@ -67,6 +96,7 @@ window.alternarTipoSlug=()=>{
const slugInput=empresaForm.querySelector('input[name="slug"]');
const nomeInput=empresaForm.querySelector('input[name="nome"]');
const btn=document.querySelector('#btn-slug-tipo');
+ limparErroModal();
if(modoSlugAuto==='sequencial'){
modoSlugAuto='nome';
if(btn)btn.textContent='Usar sequencial';
@@ -79,6 +109,7 @@ window.alternarTipoSlug=()=>{
};
window.abrirModalCadastro=()=>{
+ limparErroModal();
cadastroModal?.classList.remove('hidden');
const slugInput=empresaForm.querySelector('input[name="slug"]');
const btn=document.querySelector('#btn-slug-tipo');
@@ -86,11 +117,13 @@ window.abrirModalCadastro=()=>{
if(btn)btn.textContent='Gerar do nome';
if(slugInput){
slugInput.value=proximoSlugSequencial();
+ slugInput.style.borderColor='';
}
empresaForm.querySelector('input[name="nome"]')?.focus();
};
window.fecharModalCadastro=()=>{
+ limparErroModal();
cadastroModal?.classList.add('hidden');
};
@@ -112,20 +145,49 @@ nomeInput?.addEventListener('input',()=>{
}
});
+empresaForm.querySelector('input[name="slug"]')?.addEventListener('input',()=>{
+ limparErroModal();
+});
+
empresaForm.onsubmit=async e=>{
e.preventDefault();
+ limparErroModal();
const slugInput=empresaForm.querySelector('input[name="slug"]');
- if(slugInput&&!slugInput.value.trim()){
+ if(!slugInput) return;
+
+ if(!slugInput.value.trim()){
slugInput.value=proximoSlugSequencial();
}
+
+ const slugValor = slugInput.value.trim().toLowerCase();
+ const duplicado = empresas.find(emp => String(emp.slug || '').trim().toLowerCase() === slugValor);
+ if(duplicado){
+ const msg = `O Slug "${slugInput.value}" já está cadastrado no cliente "${duplicado.nome}". Por favor, utilize o próximo código sugerido (${proximoSlugSequencial()}).`;
+ mostrarErroModal(msg);
+ slugInput.style.borderColor = 'var(--danger)';
+ slugInput.focus();
+ Util.toast(msg, true);
+ return;
+ }
+
try{
await Api.post('/api/master/empresas',Util.formData(empresaForm));
empresaForm.reset();
fecharModalCadastro();
- Util.toast('Cliente cadastrado');
- load();
+ Util.toast('Cliente cadastrado com sucesso!');
+ await load();
}catch(err){
- Util.toast(err.message,true);
+ let msg = err.message || 'Erro ao cadastrar cliente';
+ if(msg.includes('slug_duplicado')){
+ msg = `O Slug "${slugInput.value}" já está em uso por outro cliente. Altere para outro código ou clique em "Usar sequencial".`;
+ slugInput.style.borderColor = 'var(--danger)';
+ slugInput.focus();
+ }else if(msg.includes('email_duplicado')){
+ msg = 'Este e-mail de login já está cadastrado no sistema.';
+ empresaForm.querySelector('input[name="email"]')?.focus();
+ }
+ mostrarErroModal(msg);
+ Util.toast(msg, true);
}
};