flowise1 / templates /index.html
Persano's picture
Update templates/index.html
cddb3f3 verified
raw
history blame
9.77 kB
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Comparador de Investimentos</title>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
rel="stylesheet"
/>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');
:root {
--clr-bg-light: #f9fafb;
--clr-text-light: #222;
--clr-bg-dark: #121212;
--clr-text-dark: #eee;
--clr-primary: #00c9a7;
--clr-secondary: #007cf0;
}
body {
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
min-height: 100vh;
background: var(--clr-bg-dark);
color: var(--clr-text-dark);
transition: background 0.3s, color 0.3s;
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
overflow-x: hidden;
}
body.light {
background: var(--clr-bg-light);
color: var(--clr-text-light);
}
header {
width: 100%;
max-width: 960px;
margin: 32px 16px 12px;
display: flex;
justify-content: space-between;
align-items: center;
}
h1 {
font-size: 2.8rem;
background: linear-gradient(to right, var(--clr-primary), var(--clr-secondary));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0;
user-select: none;
}
button#toggleTheme {
cursor: pointer;
font-size: 1.6rem;
background: none;
border: none;
color: var(--clr-primary);
transition: color 0.3s ease;
}
button#toggleTheme:hover {
color: var(--clr-secondary);
}
form {
background: var(--clr-bg-dark);
padding: 40px 48px;
border-radius: 20px;
box-shadow: 0 4px 25px rgba(0,0,0,0.65);
max-width: 640px;
width: 100%;
margin-bottom: 48px;
transition: background 0.3s;
}
body.light form {
background: var(--clr-bg-light);
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
}
.form-group {
margin-bottom: 24px;
position: relative;
}
label {
font-weight: 600;
display: block;
margin-bottom: 6px;
}
input[type=number], select {
width: 100%;
padding: 12px 44px 12px 16px;
font-size: 1rem;
border-radius: 10px;
border: 1px solid #333;
background-color: var(--clr-bg-dark);
color: var(--clr-text-dark);
transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}
body.light input[type=number], body.light select {
background-color: var(--clr-bg-light);
color: var(--clr-text-light);
border-color: #ccc;
}
input[type=number]:focus, select:focus {
outline: none;
border-color: var(--clr-primary);
box-shadow: 0 0 5px var(--clr-primary);
}
.icon-input {
position: absolute;
right: 16px;
top: 38px;
font-size: 1.3rem;
color: var(--clr-primary);
pointer-events: none;
}
button[type=submit] {
width: 100%;
background: linear-gradient(135deg, var(--clr-primary), var(--clr-secondary));
border: none;
border-radius: 14px;
color: white;
font-size: 1.2rem;
font-weight: 700;
padding: 16px 0;
cursor: pointer;
transition: transform 0.25s ease, box-shadow 0.25s ease;
}
button[type=submit]:hover {
transform: translateY(-3px);
box-shadow: 0 12px 30px rgba(0,201,167,0.5);
}
/* Drawer sidebar */
#drawer {
position: fixed;
top: 0;
right: -400px;
width: 400px;
max-width: 90vw;
height: 100vh;
background: var(--clr-bg-dark);
box-shadow: -4px 0 24px rgba(0,0,0,0.7);
transition: right 0.35s ease;
overflow-y: auto;
padding: 24px 28px 48px;
z-index: 1001;
}
body.light #drawer {
background: var(--clr-bg-light);
box-shadow: -4px 0 24px rgba(0,0,0,0.15);
}
#drawer.open {
right: 0;
}
#drawer h2 {
color: var(--clr-primary);
font-weight: 700;
margin-top: 0;
margin-bottom: 20px;
}
#drawer p {
line-height: 1.5;
margin-bottom: 16px;
color: inherit;
}
#drawer img {
max-width: 100%;
border-radius: 14px;
box-shadow: 0 0 16px rgba(0,0,0,0.35);
margin-bottom: 28px;
}
#drawerCloseBtn {
position: absolute;
top: 18px;
right: 18px;
background: transparent;
border: none;
font-size: 1.8rem;
cursor: pointer;
color: var(--clr-primary);
transition: color 0.3s;
}
#drawerCloseBtn:hover {
color: var(--clr-secondary);
}
/* Overlay behind drawer */
#drawerOverlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.5);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
z-index: 1000;
}
#drawerOverlay.open {
opacity: 1;
pointer-events: all;
}
@media (max-width: 700px) {
#drawer {
width: 100vw;
}
}
</style>
</head>
<body>
<header>
<h1>Comparador de Investimentos</h1>
<button id="toggleTheme" aria-label="Alternar tema claro/escuro">
<i class="fa-regular fa-sun"></i>
</button>
</header>
<form method="POST" id="formSimulador">
<div class="form-group">
<label for="capital">Capital Inicial (R$)</label>
<input type="number" name="capital" id="capital" step="1000" min="10000" placeholder="Ex: 400000" required />
<i class="fa-solid fa-wallet icon-input"></i>
</div>
<div class="form-group">
<label for="studio_ret">Retorno mensal do Studio (%)</label>
<input type="number" name="studio_ret" id="studio_ret" step="0.1" min="0" max="5" placeholder="Ex: 1.0" required />
<i class="fa-solid fa-building icon-input"></i>
</div>
<div class="form-group">
<label for="valorizacao">Valorização anual do imóvel (%)</label>
<input type="number" name="valorizacao" id="valorizacao" step="0.1" min="0" max="20" placeholder="Ex: 6.0" required />
<i class="fa-solid fa-chart-line icon-input"></i>
</div>
<div class="form-group">
<label for="franquia_ret">Lucro anual da Franquia (R$)</label>
<input type="number" name="franquia_ret" id="franquia_ret" step="1000" min="0" placeholder="Ex: 20000" required />
<i class="fa-solid fa-shop icon-input"></i>
</div>
<div class="form-group">
<label for="acoes_ret">Retorno anual em Ações (%)</label>
<input type="number" name="acoes_ret" id="acoes_ret" step="0.1" min="0" max="50" placeholder="Ex: 10.0" required />
<i class="fa-solid fa-chart-pie icon-input"></i>
</div>
<div class="form-group">
<label for="renda_fixa">Retorno anual Renda Fixa (%)</label>
<input type="number" name="renda_fixa" id="renda_fixa" step="0.1" min="0" max="30" placeholder="Ex: 9.0" required />
<i class="fa-solid fa-coins icon-input"></i>
</div>
<div class="form-group">
<label for="inflacao">Inflação anual média esperada (%)</label>
<input type="number" name="inflacao" id="inflacao" step="0.1" min="0" max="15" placeholder="Ex: 4.5" required />
<i class="fa-solid fa-percent icon-input"></i>
</div>
<button type="submit">📊 Simular Retorno</button>
</form>
<!-- Drawer Sidebar -->
<div id="drawer" aria-hidden="true" role="complementary" aria-label="Detalhes da Simulação">
<button id="drawerCloseBtn" aria-label="Fechar painel de resultados">&times;</button>
<h2>📈 Resultado da Simulação</h2>
<div id="resultadoTexto">
<!-- Conteúdo será injetado aqui -->
</div>
<div id="resultadoGrafico">
<!-- Imagem do gráfico será injetada aqui -->
</div>
</div>
<div id="drawerOverlay"></div>
<script>
const toggleThemeBtn = document.getElementById('toggleTheme');
const body = document.body;
function updateThemeIcon() {
if (body.classList.contains('light')) {
toggleThemeBtn.innerHTML = '<i class="fa-regular fa-moon"></i>';
} else {
toggleThemeBtn.innerHTML = '<i class="fa-regular fa-sun"></i>';
}
}
toggleThemeBtn.addEventListener('click', () => {
body.classList.toggle('light');
updateThemeIcon();
});
updateThemeIcon();
// Drawer functionality
const drawer = document.getElementById('drawer');
const drawerOverlay = document.getElementById('drawerOverlay');
const drawerCloseBtn = document.getElementById('drawerCloseBtn');
const form = document.getElementById('formSimulador');
const resultadoTexto = document.getElementById('resultadoTexto');
const resultadoGrafico = document.getElementById('resultadoGrafico');
function openDrawer() {
drawer.classList.add('open');
drawerOverlay.classList.add('open');
drawer.setAttribute('aria-hidden', 'false');
}
function closeDrawer() {
drawer.classList.remove('open');
drawerOverlay.classList.remove('open');
drawer.setAttribute('aria-hidden', 'true');
}
drawerCloseBtn.addEventListener('click', closeDrawer);
drawerOverlay.addEventListener('click', closeDrawer);
form.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(form);
// Enviar dados para backend via fetch POST e receber resultado JSON
// Supondo que exista um endpoint /simular que retorna { texto: "...", graficoBase64: "..." }
try {
const response = await fetch('/simular', {
method: 'POST',
body: formData,
});
if (!response.ok) throw new Error('Erro na simulação');
const data = await response.json();
resultadoTexto.innerHTML = `<p>${data.texto.replace(/\n/g, '<br>')}</p>`;
resultadoGrafico.innerHTML = `<img src="data:image/png;base64,${data.graficoBase64}" alt="Gráfico da simulação" />`;
openDrawer();
} catch (err) {
alert('Erro ao obter resultado da simulação. Tente novamente.');
console.error(err);
}
});
</script>
</body>
</html>