Arthur-Attili commited on
Commit
9a67432
·
verified ·
1 Parent(s): ae612bd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +411 -98
app.py CHANGED
@@ -1,131 +1,444 @@
1
- # app.py - BACKEND SIMPLIFICADO PARA TESTE
2
- import os
3
- os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
4
- os.environ["GRADIO_QUEUE_ENABLED"] = "False"
5
-
6
- import gradio as gr
7
  import pandas as pd
8
  import requests
9
  import io
 
10
  from collections import defaultdict
 
 
 
11
 
12
- # DADOS DE TESTE PARA INÍCIO
13
- def criar_dados_teste():
14
- """Cria dados de teste enquanto não carrega a planilha"""
15
- dados = []
16
- administradoras = ["bradesco", "santander", "itau", "caixa", "banco do brasil"]
17
-
18
- for i in range(50):
19
- dados.append({
20
- "administradora": administradoras[i % len(administradoras)],
21
- "valor_credito": 20000 + (i * 5000),
22
- "valor_entrada": 2000 + (i * 500),
23
- "valor_parcela": 300 + (i * 50),
24
- "qtd_parcelas": 60,
25
- "saldo_devedor": 18000 + (i * 4500),
26
- "codigo": f"TEST{i:03d}",
27
- "tipo_do_bem": "auto"
28
- })
29
-
30
- return pd.DataFrame(dados)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- # Variáveis globais
33
- df = criar_dados_teste()
34
- planilha_carregada = True
35
 
36
- def agrupar_por_administradora(df):
 
 
 
 
 
 
 
 
 
 
 
37
  grupos = defaultdict(list)
38
- for _, row in df.iterrows():
39
  grupos[row['administradora']].append(row.to_dict())
40
  return grupos
41
 
42
- grupos_auto = agrupar_por_administradora(df[df['tipo_do_bem'] == 'auto'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- def buscar_combinacoes_simples(credito_desejado, entrada_desejada, parcela_desejada, administradoras, max_combinacoes=5):
45
- """Busca simplificada para teste"""
46
  resultados = []
47
-
48
- for adm in administradoras:
49
- if adm in grupos_auto:
50
- for cota in grupos_auto[adm][:10]: # Limita a 10 cotas por admin
51
- credito = cota['valor_credito']
52
- entrada = cota['valor_entrada']
53
- parcela = cota['valor_parcela']
54
-
55
- # Tolerâncias simples
56
- if (0.8 * credito_desejado <= credito <= 1.2 * credito_desejado and
57
- 0.8 * entrada_desejada <= entrada <= 1.2 * entrada_desejada and
58
- 0.8 * parcela_desejada <= parcela <= 1.2 * parcela_desejada):
59
-
60
- resultados.append({
61
- "administradora": adm,
62
- "credito": credito,
63
- "entrada": entrada,
64
- "parcela": parcela,
65
- "prazo": cota['qtd_parcelas'],
66
- "saldo_devedor": cota['saldo_devedor'],
67
- "codigo": cota['codigo']
68
- })
69
-
70
- # Limita resultados
71
- return resultados[:max_combinacoes]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
  def formatar_resultados(resultados):
 
74
  if not resultados:
75
- return "Nenhuma combinação encontrada com os critérios informados."
76
-
77
  resposta = ""
78
- for i, r in enumerate(resultados, 1):
79
- resposta += f"""
80
- --- COMBINAÇÃO {i} ---
81
- 🏢 Administradora: {r['administradora']}
82
- 🔢 Código: {r['codigo']}
83
- 💰 Crédito Total: R$ {r['credito']:,.2f}
84
- 💵 Entrada: R$ {r['entrada']:,.2f}
85
- 💲 Parcela: R$ {r['parcela']:,.2f}
86
- ⏳ Prazo: {r['prazo']} meses
87
- 📉 Saldo Devedor: R$ {r['saldo_devedor']:,.2f}
 
 
 
 
 
 
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  """
90
  return resposta
91
 
 
 
 
92
  def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
93
- print(f"Recebido: Crédito={credito_desejado}, Entrada={entrada_desejada}, Parcela={parcela_desejada}, Admin={administradoras}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
- if not planilha_carregada:
96
- return "Erro: Dados não carregados"
 
 
97
 
98
- resultados = buscar_combinacoes_simples(
99
- credito_desejado, entrada_desejada, parcela_desejada,
100
- [a.lower() for a in administradoras], max_combinacoes=5
101
- )
 
 
 
 
102
 
103
- return formatar_resultados(resultados)
104
-
105
- # Interface
106
- with gr.Blocks(title="Consórcio Auto - TESTE") as demo:
107
- gr.Markdown("# 🚗 Busca de Combinações (MODO TESTE)")
 
 
108
 
109
- with gr.Row():
110
- credito = gr.Number(label="Crédito Desejado (R$)", value=30000)
111
- entrada = gr.Number(label="Entrada Desejada (R$)", value=3000)
112
- parcela = gr.Number(label="Parcela Desejada (R$)", value=500)
113
 
114
- administradoras = gr.CheckboxGroup(
115
- label="Administradoras",
116
- choices=["bradesco", "santander", "itau", "caixa", "banco do brasil"],
117
- value=["bradesco"]
118
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
- buscar_btn = gr.Button("Buscar")
121
- resultado = gr.Textbox(label="Resultados", lines=20)
 
 
122
 
123
- buscar_btn.click(
124
- ajustar_e_buscar,
125
- inputs=[credito, entrada, parcela, administradoras],
126
- outputs=resultado,
127
- api_name="ajustar_e_buscar"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  )
129
 
 
 
 
130
  if __name__ == "__main__":
131
  demo.launch()
 
1
+ # app_auto.py - VERSÃO SIMILAR AO CÓDIGO DE IMÓVEIS
 
 
 
 
 
2
  import pandas as pd
3
  import requests
4
  import io
5
+ import itertools
6
  from collections import defaultdict
7
+ import gradio as gr
8
+ import time
9
+ import math
10
 
11
+ # 🔧 CONFIGURAÇÕES GLOBAIS
12
+ FILE_ID = "1EoH8V3Fyls0mNa95VcBN6ZL1B552ty3X" # ID da planilha de auto
13
+ URL = f"https://drive.google.com/uc?export=download&id={FILE_ID}"
14
+
15
+ # Variáveis globais para armazenamento
16
+ df = None
17
+ df_auto = None
18
+ grupos_auto = None
19
+ planilha_carregada = False
20
+
21
+ def carregar_planilha():
22
+ """Carrega e prepara a planilha para análise."""
23
+ global df, df_auto, grupos_auto, planilha_carregada
24
+
25
+ if planilha_carregada:
26
+ return True
27
+
28
+ try:
29
+ print("⏳ Carregando planilha...")
30
+ response = requests.get(URL)
31
+ response.raise_for_status()
32
+ data = io.BytesIO(response.content)
33
+ df = pd.read_excel(data)
34
+
35
+ # Padroniza nomes das colunas
36
+ df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
37
+
38
+ # Converte colunas numéricas
39
+ colunas_numericas = ['valor_credito', 'valor_entrada', 'valor_parcela', 'saldo_devedor', 'qtd_parcelas']
40
+ for coluna in colunas_numericas:
41
+ if coluna in df.columns:
42
+ df[coluna] = pd.to_numeric(df[coluna], errors='coerce').fillna(0)
43
+
44
+ # Verifica colunas essenciais
45
+ if 'tipo_do_bem' not in df.columns or 'administradora' not in df.columns:
46
+ raise ValueError("Colunas essenciais não encontradas")
47
+
48
+ # Remove duplicatas
49
+ df.drop_duplicates(inplace=True)
50
 
51
+ # Pré-filtra e pré-processa dados de auto
52
+ df_auto = df[df['tipo_do_bem'].str.lower() == 'auto'].copy()
53
+ grupos_auto = agrupar_por_administradora(df_auto)
54
 
55
+ planilha_carregada = True
56
+ print("✅ Planilha carregada e pré-processada com sucesso")
57
+ print(f"✅ Total de cotas de auto: {len(df_auto)}")
58
+ print(f"✅ Administradoras disponíveis: {list(grupos_auto.keys())}")
59
+ return True
60
+
61
+ except Exception as e:
62
+ print(f"❌ Erro ao carregar planilha: {str(e)}")
63
+ return False
64
+
65
+ def agrupar_por_administradora(dataframe):
66
+ """Agrupa cotas por administradora."""
67
  grupos = defaultdict(list)
68
+ for _, row in dataframe.iterrows():
69
  grupos[row['administradora']].append(row.to_dict())
70
  return grupos
71
 
72
+ def calcular_tempo_parcelas(combinacao):
73
+ """Calcula o tempo de parcelas baseado nas cotas da combinação."""
74
+ if not combinacao:
75
+ return ""
76
+
77
+ try:
78
+ cotas_ordenadas = sorted(combinacao, key=lambda x: int(x.get('qtd_parcelas', 0)))
79
+ prazos = sorted(set(int(c.get('qtd_parcelas', 0)) for c in combinacao))
80
+
81
+ if not prazos or prazos[0] <= 0:
82
+ return ""
83
+
84
+ resultado = []
85
+ prazo_anterior = 0
86
+
87
+ for i, prazo_atual in enumerate(prazos):
88
+ cotas_ativas = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) >= prazo_anterior + 1]
89
+ valor_parcela_total = sum(c.get('valor_parcela', 0) for c in cotas_ativas)
90
+
91
+ inicio = prazo_anterior + 1
92
+ fim = prazo_atual
93
+
94
+ if inicio <= fim and valor_parcela_total > 0:
95
+ resultado.append(f"{inicio}x à {fim}x: {formatar_moeda(valor_parcela_total)}/mês")
96
+
97
+ prazo_anterior = prazo_atual
98
+
99
+ if prazos and prazo_anterior < max(prazos):
100
+ cotas_ativas_finais = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) > prazo_anterior]
101
+ if cotas_ativas_finais:
102
+ valor_parcela_final = sum(c.get('valor_parcela', 0) for c in cotas_ativas_finais)
103
+ inicio_final = prazo_anterior + 1
104
+ fim_final = max(prazos)
105
+ if valor_parcela_final > 0:
106
+ resultado.append(f"{inicio_final}x à {fim_final}x: {formatar_moeda(valor_parcela_final)}/mês")
107
+
108
+ return "\n".join(resultado) if resultado else ""
109
+
110
+ except Exception as e:
111
+ print(f"❌ Erro ao calcular tempo de parcelas: {str(e)}")
112
+ return ""
113
+
114
+ def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None, max_combinacoes=15):
115
+ """Busca combinações de cotas dentro dos parâmetros especificados de forma otimizada."""
116
+ global df_auto, grupos_auto
117
+
118
+ if not planilha_carregada:
119
+ if not carregar_planilha():
120
+ return "❌ Erro: Planilha não carregada. Por favor, tente novamente."
121
+
122
+ # Filtra administradoras se especificado
123
+ if administradoras and len(administradoras) > 0:
124
+ grupos_filtrados = {adm: cotas for adm, cotas in grupos_auto.items() if adm in administradoras}
125
+ print(f"🔍 Filtrando por administradoras: {administradoras}")
126
+ else:
127
+ grupos_filtrados = grupos_auto
128
+ print("🔍 Buscando em todas as administradoras")
129
+
130
+ if not grupos_filtrados:
131
+ return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
132
+
133
+ print(f"🔍 Total de administradoras no filtro: {len(grupos_filtrados)}")
134
+
135
+ # TOLERÂNCIAS (idênticas ao código de imóveis)
136
+ if credito_desejado > 10000000:
137
+ tolerancia_credito = 0.50
138
+ tolerancia_entrada = 0.50
139
+ tolerancia_parcela = 1.00
140
+ max_cotas_combinacao = 25
141
+ else:
142
+ tolerancia_credito = 0.25
143
+ tolerancia_entrada = 0.25
144
+ tolerancia_parcela = 0.50
145
+ max_cotas_combinacao = 15
146
+
147
+ credito_min = credito_desejado * (1 - tolerancia_credito)
148
+ credito_max = credito_desejado * (1 + tolerancia_credito)
149
+ entrada_min = entrada_desejada * (1 - tolerancia_entrada)
150
+ entrada_max = entrada_desejada * (1 + tolerancia_entrada)
151
+ parcela_min = parcela_desejada * (1 - tolerancia_parcela)
152
+ parcela_max = parcela_desejada * (1 + tolerancia_parcela)
153
+
154
+ print(f"💰 Valores desejados: Crédito: R$ {credito_desejado:,.2f}, Entrada: R$ {entrada_desejada:,.2f}, Parcela: R$ {parcela_desejada:,.2f}")
155
 
 
 
156
  resultados = []
157
+ total_combinacoes_testadas = 0
158
+
159
+ for adm, cotas in grupos_filtrados.items():
160
+ print(f"🔍 Analisando administradora: {adm} ({len(cotas)} cotas)")
161
+
162
+ cotas_para_combinar = cotas
163
+
164
+ for r in range(1, min(max_cotas_combinacao + 1, len(cotas_para_combinar) + 1)):
165
+ if credito_desejado > 10000000:
166
+ max_combinacoes_por_adm = 7000
167
+ else:
168
+ max_combinacoes_por_adm = 4000
169
+ combinacoes_geradas = 0
170
+
171
+ for combinacao in itertools.combinations(cotas_para_combinar, r):
172
+ if combinacoes_geradas >= max_combinacoes_por_adm:
173
+ break
174
+
175
+ total_combinacoes_testadas += 1
176
+ combinacoes_geradas += 1
177
+
178
+ total_credito = sum(c['valor_credito'] for c in combinacao)
179
+ total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
180
+ total_entrada = total_entrada_base + (total_credito * 0.085)
181
+ total_parcelas = sum(c['valor_parcela'] for c in combinacao)
182
+
183
+ if (credito_min <= total_credito <= credito_max and
184
+ entrada_min <= total_entrada <= entrada_max and
185
+ parcela_min <= total_parcelas <= parcela_max):
186
+
187
+ total_saldo = sum(c['saldo_devedor'] for c in combinacao)
188
+ valor_final = round(total_entrada + total_saldo, 2)
189
+ diferenca = abs(valor_final - total_credito)
190
+
191
+ resultados.append((adm, combinacao, diferenca))
192
+
193
+ if len(resultados) >= max_combinacoes * 3:
194
+ break
195
+
196
+ if len(resultados) >= max_combinacoes * 3:
197
+ break
198
+
199
+ if len(resultados) >= max_combinacoes * 3:
200
+ break
201
+
202
+ print(f"🔍 Total de combinações testadas: {total_combinacoes_testadas}")
203
+ print(f"🔍 Combinações válidas encontradas: {len(resultados)}")
204
+
205
+ if not resultados:
206
+ # Busca ampla com tolerâncias maiores
207
+ print("🔍 Nenhuma combinação encontrada. Tentando busca ampla...")
208
+ return buscar_combinacoes_amplo(credito_desejado, entrada_desejada, parcela_desejada, administradoras, max_combinacoes)
209
+
210
+ resultados.sort(key=lambda x: x[2])
211
+ return formatar_resultados(resultados[:max_combinacoes])
212
+
213
+ def buscar_combinacoes_amplo(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None, max_combinacoes=15):
214
+ """Busca combinações com tolerâncias mais amplas para valores altos."""
215
+ global grupos_auto
216
+
217
+ if administradoras and len(administradoras) > 0:
218
+ grupos_filtrados = {adm: cotas for adm, cotas in grupos_auto.items() if adm in administradoras}
219
+ else:
220
+ grupos_filtrados = grupos_auto
221
+
222
+ if credito_desejado > 10000000:
223
+ tolerancia_credito = 0.50
224
+ tolerancia_entrada = 0.50
225
+ tolerancia_parcela = 1.00
226
+ max_cotas_combinacao = 25
227
+ else:
228
+ tolerancia_credito = 0.25
229
+ tolerancia_entrada = 0.25
230
+ tolerancia_parcela = 0.50
231
+ max_cotas_combinacao = 15
232
+
233
+ credito_min = credito_desejado * (1 - tolerancia_credito)
234
+ credito_max = credito_desejado * (1 + tolerancia_credito)
235
+ entrada_min = entrada_desejada * (1 - tolerancia_entrada)
236
+ entrada_max = entrada_desejada * (1 + tolerancia_entrada)
237
+ parcela_min = parcela_desejada * (1 - tolerancia_parcela)
238
+ parcela_max = parcela_desejada * (1 + tolerancia_parcela)
239
+
240
+ resultados = []
241
+ total_combinacoes_testadas = 0
242
+
243
+ for adm, cotas in grupos_filtrados.items():
244
+ print(f"🔍 BUSCA AMPLA - Analisando administradora: {adm}")
245
+
246
+ for r in range(1, min(max_cotas_combinacao + 1, len(cotas) + 1)):
247
+ combinacoes_geradas = 0
248
+ max_combinacoes_por_adm = 7000
249
+
250
+ for combinacao in itertools.combinations(cotas, r):
251
+ if combinacoes_geradas >= max_combinacoes_por_adm:
252
+ break
253
+
254
+ total_combinacoes_testadas += 1
255
+ combinacoes_geradas += 1
256
+
257
+ total_credito = sum(c['valor_credito'] for c in combinacao)
258
+ total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
259
+ total_entrada = total_entrada_base + (total_credito * 0.085)
260
+ total_parcelas = sum(c['valor_parcela'] for c in combinacao)
261
+
262
+ if (credito_min <= total_credito <= credito_max and
263
+ entrada_min <= total_entrada <= entrada_max and
264
+ parcela_min <= total_parcelas <= parcela_max):
265
+
266
+ total_saldo = sum(c['saldo_devedor'] for c in combinacao)
267
+ valor_final = round(total_entrada + total_saldo, 2)
268
+ diferenca = abs(valor_final - total_credito)
269
+
270
+ resultados.append((adm, combinacao, diferenca))
271
+
272
+ if len(resultados) >= max_combinacoes * 2:
273
+ break
274
+
275
+ if len(resultados) >= max_combinacoes * 2:
276
+ break
277
+
278
+ if len(resultados) >= max_combinacoes * 2:
279
+ break
280
+
281
+ print(f"🔍 BUSCA AMPLA: Combinações válidas encontradas: {len(resultados)}")
282
+
283
+ if not resultados:
284
+ return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
285
+
286
+ resultados.sort(key=lambda x: x[2])
287
+ return formatar_resultados(resultados[:max_combinacoes])
288
+
289
+ def formatar_moeda(valor):
290
+ return f"R$ {valor:,.2f}".replace(",", "v").replace(".", ",").replace("v", ".")
291
 
292
  def formatar_resultados(resultados):
293
+ """Formata os resultados para exibição incluindo tempo de parcelas."""
294
  if not resultados:
295
+ return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
296
+
297
  resposta = ""
298
+ for idx, (adm, combinacao, _) in enumerate(resultados, 1):
299
+ codigos = [str(c.get('codigo', 'N/A')) for c in combinacao]
300
+ total_credito = sum(c['valor_credito'] for c in combinacao)
301
+ total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
302
+ total_entrada = total_entrada_base + (total_credito * 0.085)
303
+ total_saldo = sum(c['saldo_devedor'] for c in combinacao)
304
+ total_parcelas = sum(c['valor_parcela'] for c in combinacao)
305
+ maior_prazo = max(int(c.get('qtd_parcelas', 0)) for c in combinacao)
306
+
307
+ valor_final = round(total_entrada + total_saldo, 2)
308
+ credito_real = round(total_credito - total_entrada, 2)
309
+ taxa_total = total_saldo - credito_real
310
+ taxa_percentual = (taxa_total / credito_real) * 100 if credito_real > 0 else 0
311
+ taxa_mensal = taxa_percentual / maior_prazo if maior_prazo > 0 else 0
312
+
313
+ tempo_parcelas = calcular_tempo_parcelas(combinacao)
314
 
315
+ resposta += f"""
316
+ --- COMBINAÇÃO {idx} ---
317
+ 🏢 Administradora: {adm}
318
+ 🔢 Códigos: {', '.join(codigos)} ({len(combinacao)} cotas)
319
+ 💰 Crédito Total: {formatar_moeda(total_credito)}
320
+ 💵 Entrada (+comissão): {formatar_moeda(total_entrada)}
321
+ 📉 Saldo Devedor: {formatar_moeda(total_saldo)}
322
+ 💲 Parcela: {formatar_moeda(total_parcelas)}
323
+ ⏳ Prazo: {maior_prazo} meses
324
+ 🔚 Valor Final: {formatar_moeda(valor_final)}
325
+ 💠 Crédito Líquido: {formatar_moeda(credito_real)}
326
+ 📊 Taxa Total: {taxa_percentual:.2f}% ({formatar_moeda(taxa_total)})
327
+ 🗓️ Taxa Mensal: {taxa_mensal:.2f}%
328
+ 🗓️ Taxa Anual: {taxa_mensal * 12:.2f}%
329
+ ⏰ TEMPO DE PARCELAS:
330
+ {tempo_parcelas if tempo_parcelas else "Não foi possível calcular o tempo de parcelas"}
331
  """
332
  return resposta
333
 
334
+ # Carrega a planilha uma vez quando o aplicativo inicia
335
+ carregar_planilha()
336
+
337
  def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
338
+ return buscar_combinacoes_otimizado(
339
+ credito_desejado, entrada_desejada, parcela_desejada, administradoras, max_combinacoes=15
340
+ )
341
+
342
+ def get_administradoras_options():
343
+ if df is not None and planilha_carregada:
344
+ adm_list = df[df['tipo_do_bem'].str.lower() == 'auto']['administradora'].unique()
345
+ return sorted(adm_list)
346
+ return []
347
+
348
+ # Interface Gradio (idêntica à do imóvel, apenas com título alterado)
349
+ with gr.Blocks(title="Sistema de Busca de Consórcio Auto") as demo:
350
+ gr.HTML("""
351
+ <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
352
+ <style>
353
+ * {
354
+ font-family: 'Poppins', sans-serif !important;
355
+ }
356
 
357
+ body {
358
+ background-color: #ff8f00 !important;
359
+ color: black !important;
360
+ }
361
 
362
+ input[type="number"] {
363
+ background-color: white !important;
364
+ border: 2px solid #000 !important;
365
+ border-radius: 12px !important;
366
+ color: black !important;
367
+ padding: 10px !important;
368
+ font-weight: 500;
369
+ }
370
 
371
+ input[type="text"], textarea {
372
+ background-color: white !important;
373
+ border: 2px solid black !important;
374
+ border-radius: 12px !important;
375
+ color: black !important;
376
+ padding: 10px !important;
377
+ }
378
 
379
+ input::placeholder, textarea::placeholder {
380
+ color: #333 !important;
381
+ opacity: 0.7;
382
+ }
383
 
384
+ .gr-checkbox label {
385
+ display: flex;
386
+ align-items: center;
387
+ gap: 8px;
388
+ font-weight: 600;
389
+ }
390
+
391
+ input[type="checkbox"] {
392
+ accent-color: black !important;
393
+ width: 18px;
394
+ height: 18px;
395
+ }
396
+
397
+ .gr-button {
398
+ font-weight: bold;
399
+ border-radius: 10px !important;
400
+ background-color: white !important;
401
+ color: black !important;
402
+ border: 2px solid black !important;
403
+ }
404
 
405
+ .gr-button:hover {
406
+ background-color: #fff3e0 !important;
407
+ color: black !important;
408
+ }
409
 
410
+ label {
411
+ font-weight: 600 !important;
412
+ }
413
+ </style>
414
+ """)
415
+
416
+ gr.Markdown("# 🚗 Busca de Combinações de Consórcio Auto")
417
+ gr.Markdown("Insira os valores desejados para crédito, entrada e parcela, e filtre por administradora.")
418
+
419
+ with gr.Row():
420
+ credito_input = gr.Number(label="Crédito Desejado (R$)", value=30000, step=1000)
421
+ entrada_input = gr.Number(label="Entrada Desejada (R$)", value=3000, step=100)
422
+ parcela_input = gr.Number(label="Parcela Desejada (R$)", value=500, step=10)
423
+
424
+ administradoras_multiselect = gr.CheckboxGroup(
425
+ label="Filtrar por Administradoras",
426
+ choices=get_administradoras_options(),
427
+ value=get_administradoras_options() # Seleciona todas por padrão
428
+ )
429
+
430
+ submit_btn = gr.Button("🔍 Buscar Combinações", variant="primary")
431
+
432
+ output_text = gr.Textbox(label="Resultados da Busca", lines=20, max_lines=40, interactive=False, placeholder="Os resultados aparecerão aqui...")
433
+
434
+ submit_btn.click(
435
+ fn=ajustar_e_buscar,
436
+ inputs=[credito_input, entrada_input, parcela_input, administradoras_multiselect],
437
+ outputs=output_text
438
  )
439
 
440
+ gr.Markdown("---")
441
+ gr.Markdown("Desenvolvido para auxiliar na busca por cotas de consórcio ideais.")
442
+
443
  if __name__ == "__main__":
444
  demo.launch()