Dashboard
Visão estratégica e operacional
⚠ Manutenções nos próximos 7 dias
🏆 Ranking VIP — maiores LTVs
📊 Sazonalidade mensal
🎯 Origem dos clientes
😴 Clientes sumidos (+90 dias)
Base de Clientes
—
Cliente
Telefone
Cidade / Bairro
Origem
Status
Ações
Central de Reativação
Segmentação inteligente
Configurações
Integração e preferências
🔗 Google Sheets
Planilha com 2 abas:
clientes: id|nome|telefone|email|cidade|bairro|aniversario|origem|interesse|tags|status|nps|depoimento|ultimoContato|cadastroEm|obscompras: id|clienteId|produto|data|valor|formaPagamento|vendedor|proximaManutencao|frequencia|obs
🔐 Senha
Padrão:
admin123📋 Código Apps Script
function doGet(e) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
if (e.parameter && e.parameter.payload) {
try {
const data = JSON.parse(Utilities.newBlob(
Utilities.base64Decode(e.parameter.payload, Utilities.Charset.UTF_8)
).getDataAsString());
const sheet = ss.getSheetByName(data.sheet || 'clientes');
if (data.action === 'salvar') { sheet.appendRow(data.row); }
if (data.action === 'editar') {
const rows = sheet.getDataRange().getValues();
for (let i = 1; i < rows.length; i++) {
if (String(rows[i][0]) === String(data.id)) {
sheet.getRange(i+1,1,1,data.row.length).setValues([data.row]); break;
}
}
}
if (data.action === 'deletar') {
const rows = sheet.getDataRange().getValues();
for (let i = 1; i < rows.length; i++) {
if (String(rows[i][0]) === String(data.id)) { sheet.deleteRow(i+1); break; }
}
}
return ContentService.createTextOutput(JSON.stringify({ok:true})).setMimeType(ContentService.MimeType.JSON);
} catch(err) {
return ContentService.createTextOutput(JSON.stringify({ok:false,error:err.message})).setMimeType(ContentService.MimeType.JSON);
}
}
const which = (e.parameter && e.parameter.sheet) || 'clientes';
const sheet = ss.getSheetByName(which);
if (!sheet) return ContentService.createTextOutput('[]').setMimeType(ContentService.MimeType.JSON);
const rows = sheet.getDataRange().getValues();
if (rows.length < 2) return ContentService.createTextOutput('[]').setMimeType(ContentService.MimeType.JSON);
const headers = rows[0];
const data = rows.slice(1).map(r => { const o={}; headers.forEach((h,i)=>o[h]=r[i]); return o; });
return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(ContentService.MimeType.JSON);
}