Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/pages-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Deploy GitHub Pages

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ccca965b81a2b50b036a2a # v4.2.2

- name: Inject HubSpot form config (secrets only — never commit keys)
env:
HUBSPOT_PORTAL_ID: ${{ secrets.HUBSPOT_PORTAL_ID }}
HUBSPOT_DEMO_FORM_GUID: ${{ secrets.HUBSPOT_DEMO_FORM_GUID }}
HUBSPOT_REGION: ${{ secrets.HUBSPOT_REGION }}
run: |
mkdir -p js
REGION="${HUBSPOT_REGION:-na1}"
cat > js/form-config.js <<EOF
window.DATA_BOAR_FORM_CONFIG = {
hubspot: {
portalId: "${HUBSPOT_PORTAL_ID}",
demoFormGuid: "${HUBSPOT_DEMO_FORM_GUID}",
region: "${REGION}",
},
fallbackMailto: "contact@databoar.com.br",
};
EOF

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@56afc609e74203658a474b165d2ec89d7f9b06d9 # v3.0.1
with:
path: .

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e8febac5b3c4c40c # v4.0.5
37 changes: 20 additions & 17 deletions agende-demonstracao.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,23 @@ <h3>Decida com confiança</h3>

<div class="demo-form-card">
<h2>Formulário de agendamento</h2>
<form onsubmit="event.preventDefault();">
<form id="demo-request-form">
<div class="form-grid">
<div class="form-field">
<label>Nome completo*</label>
<input type="text" placeholder="Digite seu nome" required>
<label for="demo-nome">Nome completo*</label>
<input type="text" id="demo-nome" name="nome_completo" placeholder="Digite seu nome" required>
</div>
<div class="form-field">
<label>E-mail corporativo*</label>
<input type="email" placeholder="seu@email.com" required>
<label for="demo-email">E-mail corporativo*</label>
<input type="email" id="demo-email" name="email" placeholder="seu@email.com" required>
</div>
<div class="form-field">
<label>Empresa*</label>
<input type="text" placeholder="Digite o nome da empresa" required>
<label for="demo-empresa">Empresa*</label>
<input type="text" id="demo-empresa" name="company" placeholder="Digite o nome da empresa" required>
</div>
<div class="form-field">
<label>Cargo*</label>
<select required>
<label for="demo-cargo">Cargo*</label>
<select id="demo-cargo" name="jobtitle" required>
<option value="" selected disabled>Selecione seu cargo</option>
<option>Diretoria / C-level</option>
<option>Gerência</option>
Expand All @@ -119,12 +119,12 @@ <h2>Formulário de agendamento</h2>
</select>
</div>
<div class="form-field">
<label>Telefone / WhatsApp*</label>
<input type="tel" placeholder="(11) 99999-9999" required>
<label for="demo-telefone">Telefone / WhatsApp*</label>
<input type="tel" id="demo-telefone" name="phone" placeholder="(11) 99999-9999" required>
</div>
<div class="form-field">
<label>Segmento*</label>
<select required>
<label for="demo-segmento">Segmento*</label>
<select id="demo-segmento" name="segmento" required>
<option value="" selected disabled>Selecione o segmento</option>
<option>Financeiro</option>
<option>Varejo</option>
Expand All @@ -135,15 +135,16 @@ <h2>Formulário de agendamento</h2>
</select>
</div>
<div class="form-field full">
<label>Qual o principal desafio que você deseja resolver?*</label>
<textarea placeholder="Conte-nos um pouco sobre o seu desafio" required></textarea>
<label for="demo-desafio">Qual o principal desafio que você deseja resolver?*</label>
<textarea id="demo-desafio" name="message" placeholder="Conte-nos um pouco sobre o seu desafio" required></textarea>
</div>
<div class="form-field full">
<label>Quando você gostaria de agendar?</label>
<input type="text" placeholder="Selecione a melhor data e horário" onfocus="(this.type='datetime-local')">
<label for="demo-agendamento">Quando você gostaria de agendar?</label>
<input type="text" id="demo-agendamento" name="demo_preferred_datetime" placeholder="Selecione a melhor data e horário" onfocus="(this.type='datetime-local')">
</div>
</div>
<button type="submit" class="btn btn-primary form-submit">Agendar demonstração →</button>
<div id="demo-form-status" class="form-status" role="status" aria-live="polite" hidden></div>
<div class="form-note">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="10" width="16" height="10" rx="2"/><path d="M8 10V7a4 4 0 018 0v3"/></svg>
Seus dados estão seguros conosco.
Expand Down Expand Up @@ -191,6 +192,8 @@ <h4>Conformidade</h4>
</div>
</footer>

<script src="js/form-config.js"></script>
<script src="js/forms.js"></script>
<script>
document.querySelectorAll('.lang-option').forEach(function(opt){
opt.addEventListener('click', function(e){
Expand Down
7 changes: 7 additions & 0 deletions css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,13 @@
font-size:12px; color:var(--color-text-secondary); margin-top:14px;
}
.form-note svg{width:13px; height:13px;}
.form-status{
margin-top:14px; padding:12px 16px; border-radius:var(--radius-sm);
font-size:14px; line-height:1.45;
}
.form-status.is-success{background:#f0fdf4; color:#166534; border:1px solid #bbf7d0;}
.form-status.is-error{background:#fef2f2; color:#991b1b; border:1px solid #fecaca;}
.form-status.is-info{background:#eff6ff; color:#1e40af; border:1px solid #bfdbfe;}

@media (max-width:900px){
.demo-hero-grid{grid-template-columns:1fr;}
Expand Down
52 changes: 52 additions & 0 deletions docs/HUBSPOT_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# HubSpot lead capture (GitHub Pages)

The demo form on `agende-demonstracao.html` submits leads via HubSpot's **public** form
integration endpoint (`portalId` + `formGuid`). A **private** HubSpot API key must **never**
ship in this repository or in browser JavaScript.

## GitHub Actions secrets

In **DataBoar/data-boar-site** → Settings → Secrets and variables → Actions, set:

| Secret | Description |
| ------ | ----------- |
| `HUBSPOT_PORTAL_ID` | HubSpot account portal ID |
| `HUBSPOT_DEMO_FORM_GUID` | GUID of the "Agendar demonstração" form |
| `HUBSPOT_REGION` | Optional; default `na1` (use `eu1` for EU portals) |

The workflow `.github/workflows/pages-deploy.yml` writes `js/form-config.js` from these
secrets at deploy time only.

## Enable Actions-based Pages deploy

1. Settings → Pages → Build and deployment → Source: **GitHub Actions**
2. Merge a PR that includes `pages-deploy.yml`
3. Confirm the workflow run injects config and publishes the site

Until secrets exist, the form shows a **mailto fallback** (`contact@databoar.com.br`) instead
of failing silently.

## HubSpot form field mapping

Align the HubSpot form with these `name` attributes (see `js/forms.js`):

| Form label (PT) | HubSpot property |
| --------------- | ---------------- |
| Nome completo | `firstname` + `lastname` (split on first space) |
| E-mail corporativo | `email` |
| Empresa | `company` |
| Cargo | `jobtitle` |
| Telefone | `phone` |
| Segmento + desafio + data | combined in `message` |

Custom HubSpot properties require updating the field list in `js/forms.js`.

## Login page

`login.html` does not send credentials to HubSpot. Submit shows an "em breve" message and
points visitors to the demo form until product SSO is wired.

## Out of scope (operator only)

- DNS, Cloudflare, custom domain, MX records
- Storing private HubSpot app tokens in the repo
9 changes: 9 additions & 0 deletions js/form-config.example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* Copy to form-config.js for local testing only — never commit real portal IDs if policy forbids. */
window.DATA_BOAR_FORM_CONFIG = {
hubspot: {
portalId: 'YOUR_PORTAL_ID',
demoFormGuid: 'YOUR_FORM_GUID',
region: 'na1',
},
fallbackMailto: 'contact@databoar.com.br',
};
9 changes: 9 additions & 0 deletions js/form-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* Injected at deploy from GitHub Actions secrets — do not put API keys here. */
window.DATA_BOAR_FORM_CONFIG = {
hubspot: {
portalId: '',
demoFormGuid: '',
region: 'na1',
},
fallbackMailto: 'contact@databoar.com.br',
};
160 changes: 160 additions & 0 deletions js/forms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
(function () {
'use strict';

var config = window.DATA_BOAR_FORM_CONFIG || {};
var hubspot = config.hubspot || {};

function showStatus(elementId, message, kind) {
var el = document.getElementById(elementId);
if (!el) return;
el.hidden = false;
el.textContent = '';
el.className = 'form-status is-' + (kind || 'info');
el.appendChild(document.createTextNode(message));
}

function splitName(fullName) {
var parts = fullName.trim().split(/\s+/).filter(Boolean);
if (!parts.length) {
return { firstname: '', lastname: '' };
}
if (parts.length === 1) {
return { firstname: parts[0], lastname: '' };
}
return {
firstname: parts[0],
lastname: parts.slice(1).join(' '),
};
}

function hubspotConfigured() {
return Boolean(hubspot.portalId && hubspot.demoFormGuid);
}

function submitDemoToHubSpot(form) {
var nome = form.querySelector('[name="nome_completo"]');
var email = form.querySelector('[name="email"]');
var empresa = form.querySelector('[name="company"]');
var cargo = form.querySelector('[name="jobtitle"]');
var telefone = form.querySelector('[name="phone"]');
var segmento = form.querySelector('[name="segmento"]');
var desafio = form.querySelector('[name="message"]');
var agendamento = form.querySelector('[name="demo_preferred_datetime"]');

var nameParts = splitName(nome ? nome.value : '');
var fields = [
{ objectTypeId: '0-1', name: 'firstname', value: nameParts.firstname },
{ objectTypeId: '0-1', name: 'lastname', value: nameParts.lastname },
{ objectTypeId: '0-1', name: 'email', value: email ? email.value.trim() : '' },
{ objectTypeId: '0-1', name: 'company', value: empresa ? empresa.value.trim() : '' },
{ objectTypeId: '0-1', name: 'jobtitle', value: cargo ? cargo.value : '' },
{ objectTypeId: '0-1', name: 'phone', value: telefone ? telefone.value.trim() : '' },
{
objectTypeId: '0-1',
name: 'message',
value: [
desafio ? desafio.value.trim() : '',
segmento && segmento.value ? 'Segmento: ' + segmento.value : '',
agendamento && agendamento.value
? 'Preferência de agendamento: ' + agendamento.value
: '',
]
.filter(Boolean)
.join('\n\n'),
},
].filter(function (field) {
return field.value;
});

var endpoint =
'https://api.hsforms.com/submissions/v3/integration/submit/' +
encodeURIComponent(hubspot.portalId) +
'/' +
encodeURIComponent(hubspot.demoFormGuid);

return fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fields: fields,
context: {
pageUri: window.location.href,
pageName: document.title,
},
}),
});
}

var demoForm = document.getElementById('demo-request-form');
if (demoForm) {
demoForm.addEventListener('submit', function (event) {
event.preventDefault();
if (!demoForm.reportValidity()) {
return;
}

var submitBtn = demoForm.querySelector('[type="submit"]');
var statusId = 'demo-form-status';

if (!hubspotConfigured()) {
var mailto = config.fallbackMailto || 'contact@databoar.com.br';
showStatus(
statusId,
'Captura online em configuração. Envie um e-mail para ' +
mailto +
' para agendar sua demonstração.',
'info'
);
return;
}

if (submitBtn) {
submitBtn.disabled = true;
submitBtn.dataset.originalLabel = submitBtn.textContent;
submitBtn.textContent = 'Enviando…';
}

submitDemoToHubSpot(demoForm)
.then(function (response) {
if (!response.ok) {
throw new Error('HubSpot submit failed: ' + response.status);
}
demoForm.reset();
showStatus(
statusId,
'Recebemos seu pedido. Nossa equipe entrará em contato em breve.',
'success'
);
})
.catch(function () {
showStatus(
statusId,
'Não foi possível enviar agora. Tente novamente ou escreva para ' +
(config.fallbackMailto || 'contact@databoar.com.br') +
'.',
'error'
);
})
.finally(function () {
if (submitBtn) {
submitBtn.disabled = false;
if (submitBtn.dataset.originalLabel) {
submitBtn.textContent = submitBtn.dataset.originalLabel;
}
}
});
});
}

var loginForm = document.getElementById('login-form');
if (loginForm) {
loginForm.addEventListener('submit', function (event) {
event.preventDefault();
showStatus(
'login-form-status',
'O painel do dataBOAR estará disponível em breve. Agende uma demonstração para conhecer a plataforma.',
'info'
);
});
}
})();
Loading