Persano commited on
Commit
0147f30
·
verified ·
1 Parent(s): 0586bcf

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +209 -327
templates/index.html CHANGED
@@ -1,346 +1,228 @@
1
  <!DOCTYPE html>
2
  <html lang="pt-BR">
3
  <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Comparador de Investimentos</title>
7
- <link
8
- href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
9
- rel="stylesheet"
10
- />
11
- <style>
12
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');
13
- :root {
14
- --clr-bg-light: #f9fafb;
15
- --clr-text-light: #222;
16
- --clr-bg-dark: #121212;
17
- --clr-text-dark: #eee;
18
- --clr-primary: #00c9a7;
19
- --clr-secondary: #007cf0;
20
- }
21
- body {
22
- font-family: 'Inter', sans-serif;
23
- margin: 0;
24
- padding: 0;
25
- min-height: 100vh;
26
- background: var(--clr-bg-dark);
27
- color: var(--clr-text-dark);
28
- transition: background 0.3s, color 0.3s;
29
- display: flex;
30
- flex-direction: column;
31
- align-items: center;
32
- justify-content: start;
33
- overflow-x: hidden;
34
- }
35
- body.light {
36
- background: var(--clr-bg-light);
37
- color: var(--clr-text-light);
38
- }
39
- header {
40
- width: 100%;
41
- max-width: 960px;
42
- margin: 32px 16px 12px;
43
- display: flex;
44
- justify-content: space-between;
45
- align-items: center;
46
- }
47
- h1 {
48
- font-size: 2.8rem;
49
- background: linear-gradient(to right, var(--clr-primary), var(--clr-secondary));
50
- -webkit-background-clip: text;
51
- -webkit-text-fill-color: transparent;
52
- margin: 0;
53
- user-select: none;
54
- }
55
- button#toggleTheme {
56
- cursor: pointer;
57
- font-size: 1.6rem;
58
- background: none;
59
- border: none;
60
- color: var(--clr-primary);
61
- transition: color 0.3s ease;
62
- }
63
- button#toggleTheme:hover {
64
- color: var(--clr-secondary);
65
- }
66
- form {
67
- background: var(--clr-bg-dark);
68
- padding: 40px 48px;
69
- border-radius: 20px;
70
- box-shadow: 0 4px 25px rgba(0,0,0,0.65);
71
- max-width: 640px;
72
- width: 100%;
73
- margin-bottom: 48px;
74
- transition: background 0.3s;
75
- }
76
- body.light form {
77
- background: var(--clr-bg-light);
78
- box-shadow: 0 4px 20px rgba(0,0,0,0.1);
79
- }
80
- .form-group {
81
- margin-bottom: 24px;
82
- position: relative;
83
- }
84
- label {
85
- font-weight: 600;
86
- display: block;
87
- margin-bottom: 6px;
88
- }
89
- input[type=number], select {
90
- width: 100%;
91
- padding: 12px 44px 12px 16px;
92
- font-size: 1rem;
93
- border-radius: 10px;
94
- border: 1px solid #333;
95
- background-color: var(--clr-bg-dark);
96
- color: var(--clr-text-dark);
97
- transition: background-color 0.3s, color 0.3s, border-color 0.3s;
98
- }
99
- body.light input[type=number], body.light select {
100
- background-color: var(--clr-bg-light);
101
- color: var(--clr-text-light);
102
- border-color: #ccc;
103
- }
104
- input[type=number]:focus, select:focus {
105
- outline: none;
106
- border-color: var(--clr-primary);
107
- box-shadow: 0 0 5px var(--clr-primary);
108
- }
109
- .icon-input {
110
- position: absolute;
111
- right: 16px;
112
- top: 38px;
113
- font-size: 1.3rem;
114
- color: var(--clr-primary);
115
- pointer-events: none;
116
- }
117
- button[type=submit] {
118
- width: 100%;
119
- background: linear-gradient(135deg, var(--clr-primary), var(--clr-secondary));
120
- border: none;
121
- border-radius: 14px;
122
- color: white;
123
- font-size: 1.2rem;
124
- font-weight: 700;
125
- padding: 16px 0;
126
- cursor: pointer;
127
- transition: transform 0.25s ease, box-shadow 0.25s ease;
128
- }
129
- button[type=submit]:hover {
130
- transform: translateY(-3px);
131
- box-shadow: 0 12px 30px rgba(0,201,167,0.5);
132
- }
133
-
134
- /* Drawer sidebar */
135
- #drawer {
136
- position: fixed;
137
- top: 0;
138
- right: -400px;
139
- width: 400px;
140
- max-width: 90vw;
141
- height: 100vh;
142
- background: var(--clr-bg-dark);
143
- box-shadow: -4px 0 24px rgba(0,0,0,0.7);
144
- transition: right 0.35s ease;
145
- overflow-y: auto;
146
- padding: 24px 28px 48px;
147
- z-index: 1001;
148
- }
149
- body.light #drawer {
150
- background: var(--clr-bg-light);
151
- box-shadow: -4px 0 24px rgba(0,0,0,0.15);
152
- }
153
- #drawer.open {
154
- right: 0;
155
- }
156
- #drawer h2 {
157
- color: var(--clr-primary);
158
- font-weight: 700;
159
- margin-top: 0;
160
- margin-bottom: 20px;
161
- }
162
- #drawer p {
163
- line-height: 1.5;
164
- margin-bottom: 16px;
165
- color: inherit;
166
- }
167
- #drawer img {
168
- max-width: 100%;
169
- border-radius: 14px;
170
- box-shadow: 0 0 16px rgba(0,0,0,0.35);
171
- margin-bottom: 28px;
172
- }
173
- #drawerCloseBtn {
174
- position: absolute;
175
- top: 18px;
176
- right: 18px;
177
- background: transparent;
178
- border: none;
179
- font-size: 1.8rem;
180
- cursor: pointer;
181
- color: var(--clr-primary);
182
- transition: color 0.3s;
183
- }
184
- #drawerCloseBtn:hover {
185
- color: var(--clr-secondary);
186
- }
187
-
188
- /* Overlay behind drawer */
189
- #drawerOverlay {
190
- position: fixed;
191
- top: 0;
192
- left: 0;
193
- width: 100vw;
194
- height: 100vh;
195
- background: rgba(0,0,0,0.5);
196
- opacity: 0;
197
- pointer-events: none;
198
- transition: opacity 0.3s ease;
199
- z-index: 1000;
200
- }
201
- #drawerOverlay.open {
202
- opacity: 1;
203
- pointer-events: all;
204
- }
205
-
206
- @media (max-width: 700px) {
207
- #drawer {
208
- width: 100vw;
209
  }
210
- }
211
- </style>
212
- </head>
213
- <body>
214
- <header>
215
- <h1>Comparador de Investimentos</h1>
216
- <button id="toggleTheme" aria-label="Alternar tema claro/escuro">
217
- <i class="fa-regular fa-sun"></i>
218
- </button>
219
- </header>
220
-
221
- <form method="POST" id="formSimulador">
222
- <div class="form-group">
223
- <label for="capital">Capital Inicial (R$)</label>
224
- <input type="number" name="capital" id="capital" step="1000" min="10000" placeholder="Ex: 400000" required />
225
- <i class="fa-solid fa-wallet icon-input"></i>
226
- </div>
227
-
228
- <div class="form-group">
229
- <label for="studio_ret">Retorno mensal do Studio (%)</label>
230
- <input type="number" name="studio_ret" id="studio_ret" step="0.1" min="0" max="5" placeholder="Ex: 1.0" required />
231
- <i class="fa-solid fa-building icon-input"></i>
232
- </div>
233
-
234
- <div class="form-group">
235
- <label for="valorizacao">Valorização anual do imóvel (%)</label>
236
- <input type="number" name="valorizacao" id="valorizacao" step="0.1" min="0" max="20" placeholder="Ex: 6.0" required />
237
- <i class="fa-solid fa-chart-line icon-input"></i>
238
- </div>
239
-
240
- <div class="form-group">
241
- <label for="franquia_ret">Lucro anual da Franquia (R$)</label>
242
- <input type="number" name="franquia_ret" id="franquia_ret" step="1000" min="0" placeholder="Ex: 20000" required />
243
- <i class="fa-solid fa-shop icon-input"></i>
244
- </div>
245
-
246
- <div class="form-group">
247
- <label for="acoes_ret">Retorno anual em Ações (%)</label>
248
- <input type="number" name="acoes_ret" id="acoes_ret" step="0.1" min="0" max="50" placeholder="Ex: 10.0" required />
249
- <i class="fa-solid fa-chart-pie icon-input"></i>
250
- </div>
251
-
252
- <div class="form-group">
253
- <label for="renda_fixa">Retorno anual Renda Fixa (%)</label>
254
- <input type="number" name="renda_fixa" id="renda_fixa" step="0.1" min="0" max="30" placeholder="Ex: 9.0" required />
255
- <i class="fa-solid fa-coins icon-input"></i>
256
- </div>
257
-
258
- <div class="form-group">
259
- <label for="inflacao">Inflação anual média esperada (%)</label>
260
- <input type="number" name="inflacao" id="inflacao" step="0.1" min="0" max="15" placeholder="Ex: 4.5" required />
261
- <i class="fa-solid fa-percent icon-input"></i>
262
- </div>
263
-
264
- <button type="submit">📊 Simular Retorno</button>
265
- </form>
266
-
267
- <!-- Drawer Sidebar -->
268
- <div id="drawer" aria-hidden="true" role="complementary" aria-label="Detalhes da Simulação">
269
- <button id="drawerCloseBtn" aria-label="Fechar painel de resultados">&times;</button>
270
- <h2>📈 Resultado da Simulação</h2>
271
- <div id="resultadoTexto">
272
- <!-- Conteúdo será injetado aqui -->
273
- </div>
274
- <div id="resultadoGrafico">
275
- <!-- Imagem do gráfico será injetada aqui -->
276
- </div>
277
- </div>
278
 
279
- <div id="drawerOverlay"></div>
 
 
 
 
 
280
 
281
- <script>
282
- const toggleThemeBtn = document.getElementById('toggleTheme');
283
- const body = document.body;
 
 
 
 
 
 
 
 
 
284
 
285
- function updateThemeIcon() {
286
- if (body.classList.contains('light')) {
287
- toggleThemeBtn.innerHTML = '<i class="fa-regular fa-moon"></i>';
288
- } else {
289
- toggleThemeBtn.innerHTML = '<i class="fa-regular fa-sun"></i>';
290
  }
291
- }
292
 
293
- toggleThemeBtn.addEventListener('click', () => {
294
- body.classList.toggle('light');
295
- updateThemeIcon();
296
- });
297
- updateThemeIcon();
 
 
 
 
 
 
298
 
299
- // Drawer functionality
300
- const drawer = document.getElementById('drawer');
301
- const drawerOverlay = document.getElementById('drawerOverlay');
302
- const drawerCloseBtn = document.getElementById('drawerCloseBtn');
303
- const form = document.getElementById('formSimulador');
304
- const resultadoTexto = document.getElementById('resultadoTexto');
305
- const resultadoGrafico = document.getElementById('resultadoGrafico');
306
 
307
- function openDrawer() {
308
- drawer.classList.add('open');
309
- drawerOverlay.classList.add('open');
310
- drawer.setAttribute('aria-hidden', 'false');
311
- }
312
- function closeDrawer() {
313
- drawer.classList.remove('open');
314
- drawerOverlay.classList.remove('open');
315
- drawer.setAttribute('aria-hidden', 'true');
316
- }
 
 
 
317
 
318
- drawerCloseBtn.addEventListener('click', closeDrawer);
319
- drawerOverlay.addEventListener('click', closeDrawer);
 
 
 
320
 
321
- form.addEventListener('submit', async (e) => {
322
- e.preventDefault();
 
 
 
 
323
 
324
- const formData = new FormData(form);
325
- // Enviar dados para backend via fetch POST e receber resultado JSON
326
- // Supondo que exista um endpoint /simular que retorna { texto: "...", graficoBase64: "..." }
327
- try {
328
- const response = await fetch('/simular', {
329
- method: 'POST',
330
- body: formData,
331
- });
332
- if (!response.ok) throw new Error('Erro na simulação');
333
- const data = await response.json();
334
 
335
- resultadoTexto.innerHTML = `<p>${data.texto.replace(/\n/g, '<br>')}</p>`;
336
- resultadoGrafico.innerHTML = `<img src="data:image/png;base64,${data.graficoBase64}" alt="Gráfico da simulação" />`;
 
 
 
 
337
 
338
- openDrawer();
339
- } catch (err) {
340
- alert('Erro ao obter resultado da simulação. Tente novamente.');
341
- console.error(err);
342
  }
343
- });
344
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  </body>
346
  </html>
 
 
1
  <!DOCTYPE html>
2
  <html lang="pt-BR">
3
  <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>⭐ Comparador de Investimentos</title>
7
+ <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
9
+
10
+ body {
11
+ margin: 0;
12
+ font-family: 'Roboto', sans-serif;
13
+ background: linear-gradient(135deg, #1e3c72, #2a5298);
14
+ color: #f5f5f5;
15
+ display: flex;
16
+ flex-direction: column;
17
+ align-items: center;
18
+ min-height: 100vh;
19
+ padding: 40px 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ h1 {
23
+ font-weight: 700;
24
+ font-size: 2.8rem;
25
+ margin-bottom: 1rem;
26
+ text-shadow: 0 2px 5px rgba(0,0,0,0.4);
27
+ }
28
 
29
+ form {
30
+ background: rgba(255, 255, 255, 0.12);
31
+ backdrop-filter: blur(12px);
32
+ padding: 30px 40px;
33
+ border-radius: 16px;
34
+ box-shadow: 0 8px 30px rgba(0,0,0,0.3);
35
+ width: 100%;
36
+ max-width: 600px;
37
+ display: flex;
38
+ flex-direction: column;
39
+ gap: 20px;
40
+ }
41
 
42
+ label {
43
+ font-weight: 600;
44
+ font-size: 1.1rem;
45
+ margin-bottom: 6px;
46
+ color: #cbd5e1;
47
  }
 
48
 
49
+ input[type="number"] {
50
+ padding: 12px 14px;
51
+ border-radius: 12px;
52
+ border: none;
53
+ font-size: 1rem;
54
+ font-weight: 400;
55
+ color: #333;
56
+ outline-offset: 2px;
57
+ outline-color: transparent;
58
+ transition: outline-color 0.25s ease;
59
+ }
60
 
61
+ input[type="number"]:focus {
62
+ outline-color: #00f0b3;
63
+ }
 
 
 
 
64
 
65
+ button[type="submit"], button[type="button"] {
66
+ margin-top: 10px;
67
+ padding: 14px 22px;
68
+ font-size: 1.2rem;
69
+ font-weight: 700;
70
+ color: #0f3443;
71
+ background: #00f0b3;
72
+ border: none;
73
+ border-radius: 14px;
74
+ cursor: pointer;
75
+ box-shadow: 0 4px 12px #00f0b3aa;
76
+ transition: background-color 0.3s ease, box-shadow 0.3s ease;
77
+ }
78
 
79
+ button[type="submit"]:hover,
80
+ button[type="button"]:hover {
81
+ background-color: #00d9a0;
82
+ box-shadow: 0 6px 18px #00d9a0cc;
83
+ }
84
 
85
+ .grafico-container {
86
+ margin-top: 50px;
87
+ text-align: center;
88
+ max-width: 720px;
89
+ width: 100%;
90
+ }
91
 
92
+ .grafico-container h2 {
93
+ font-size: 2rem;
94
+ margin-bottom: 25px;
95
+ color: #e0f7fa;
96
+ text-shadow: 0 2px 6px rgba(0,0,0,0.5);
97
+ }
 
 
 
 
98
 
99
+ .grafico-container img {
100
+ width: 100%;
101
+ border-radius: 16px;
102
+ box-shadow: 0 8px 24px rgba(0,0,0,0.4);
103
+ user-select: none;
104
+ }
105
 
106
+ .download-form {
107
+ margin-top: 25px;
108
+ display: flex;
109
+ justify-content: center;
110
  }
111
+ </style>
112
+ </head>
113
+ <body>
114
+ <h1>⭐ Comparador de Investimentos</h1>
115
+
116
+ <form method="POST" action="/">
117
+ <label for="capital">Capital Inicial (R$):</label>
118
+ <input
119
+ type="number"
120
+ id="capital"
121
+ name="capital"
122
+ min="10000"
123
+ step="1000"
124
+ placeholder="Ex: 400000"
125
+ required
126
+ value="{{ capital if capital else '' }}"
127
+ />
128
+
129
+ <label for="studio_ret">Retorno mensal do Studio (%):</label>
130
+ <input
131
+ type="number"
132
+ id="studio_ret"
133
+ name="studio_ret"
134
+ min="0"
135
+ max="5"
136
+ step="0.1"
137
+ placeholder="Ex: 1.0"
138
+ required
139
+ value="{{ studio_ret if studio_ret else '' }}"
140
+ />
141
+
142
+ <label for="valorizacao">Valorização anual do imóvel (%):</label>
143
+ <input
144
+ type="number"
145
+ id="valorizacao"
146
+ name="valorizacao"
147
+ min="0"
148
+ max="20"
149
+ step="0.1"
150
+ placeholder="Ex: 6.0"
151
+ required
152
+ value="{{ valorizacao if valorizacao else '' }}"
153
+ />
154
+
155
+ <label for="franquia_ret">Lucro anual da Franquia (R$):</label>
156
+ <input
157
+ type="number"
158
+ id="franquia_ret"
159
+ name="franquia_ret"
160
+ min="0"
161
+ step="1000"
162
+ placeholder="Ex: 20000"
163
+ required
164
+ value="{{ franquia_ret if franquia_ret else '' }}"
165
+ />
166
+
167
+ <label for="acoes_ret">Retorno anual em Ações (%):</label>
168
+ <input
169
+ type="number"
170
+ id="acoes_ret"
171
+ name="acoes_ret"
172
+ min="0"
173
+ max="50"
174
+ step="0.1"
175
+ placeholder="Ex: 10.0"
176
+ required
177
+ value="{{ acoes_ret if acoes_ret else '' }}"
178
+ />
179
+
180
+ <label for="renda_fixa">Retorno anual Renda Fixa (%):</label>
181
+ <input
182
+ type="number"
183
+ id="renda_fixa"
184
+ name="renda_fixa"
185
+ min="0"
186
+ max="30"
187
+ step="0.1"
188
+ placeholder="Ex: 9.0"
189
+ required
190
+ value="{{ renda_fixa if renda_fixa else '' }}"
191
+ />
192
+
193
+ <label for="inflacao">Inflação anual média esperada (%):</label>
194
+ <input
195
+ type="number"
196
+ id="inflacao"
197
+ name="inflacao"
198
+ min="0"
199
+ max="15"
200
+ step="0.1"
201
+ placeholder="Ex: 4.5"
202
+ required
203
+ value="{{ inflacao if inflacao else '' }}"
204
+ />
205
+
206
+ <button type="submit">📊 Simular Retorno</button>
207
+ </form>
208
+
209
+ {% if grafico %}
210
+ <div class="grafico-container">
211
+ <h2>📈 Resultado da Simulação</h2>
212
+ <img src="data:image/png;base64,{{ grafico }}" alt="Gráfico de Investimento" />
213
+
214
+ <form method="POST" action="/download_excel" class="download-form">
215
+ <input type="hidden" name="capital" value="{{ capital }}" />
216
+ <input type="hidden" name="studio_ret" value="{{ studio_ret }}" />
217
+ <input type="hidden" name="valorizacao" value="{{ valorizacao }}" />
218
+ <input type="hidden" name="franquia_ret" value="{{ franquia_ret }}" />
219
+ <input type="hidden" name="acoes_ret" value="{{ acoes_ret }}" />
220
+ <input type="hidden" name="renda_fixa" value="{{ renda_fixa }}" />
221
+ <input type="hidden" name="inflacao" value="{{ inflacao }}" />
222
+ <button type="submit">📄 Baixar Excel (.xlsx)</button>
223
+ </form>
224
+ </div>
225
+ {% endif %}
226
  </body>
227
  </html>
228
+