107 lines
4.1 KiB
Python
107 lines
4.1 KiB
Python
import pandas as pd
|
|
import streamlit as st
|
|
from api_client import APIClient
|
|
|
|
def render_analytical_table_view(api_client: APIClient):
|
|
st.title("📊 Tabela Analítica & Exportação de Leads")
|
|
st.caption("Filtre, analise e exporte seus leads nos formatos CSV e JSON.")
|
|
|
|
leads = api_client.get_leads()
|
|
|
|
# Controles de Exportação
|
|
exp_col1, exp_col2, _ = st.columns([1, 1, 2])
|
|
with exp_col1:
|
|
csv_bytes = api_client.export_leads_data('csv')
|
|
st.download_button(
|
|
label="📥 Exportar em CSV",
|
|
data=csv_bytes,
|
|
file_name="leads_leadradar.csv",
|
|
mime="text/csv",
|
|
use_container_width=True
|
|
)
|
|
|
|
with exp_col2:
|
|
json_bytes = api_client.export_leads_data('json')
|
|
st.download_button(
|
|
label="📥 Exportar em JSON",
|
|
data=json_bytes,
|
|
file_name="leads_leadradar.json",
|
|
mime="application/json",
|
|
use_container_width=True
|
|
)
|
|
|
|
st.markdown("---")
|
|
|
|
# Filtros Avançados
|
|
f1, f2, f3, f4 = st.columns(4)
|
|
with f1:
|
|
search = st.text_input("🔍 Busca Geral:", value="", key="tbl_search")
|
|
with f2:
|
|
statuses = ["Todos", "novo", "contatado", "respondeu", "negociacao", "ganho", "perdido", "opt_out"]
|
|
status_sel = st.selectbox("Status Funil:", statuses, key="tbl_status")
|
|
with f3:
|
|
cidades = ["Todas"] + sorted(list(set(l.get('cidade', '') for l in leads if l.get('cidade'))))
|
|
cidade_sel = st.selectbox("Cidade:", cidades, key="tbl_cidade")
|
|
with f4:
|
|
ramos = ["Todos"] + sorted(list(set(l.get('ramo_atividade', '') for l in leads if l.get('ramo_atividade'))))
|
|
ramo_sel = st.selectbox("Ramo:", ramos, key="tbl_ramo")
|
|
|
|
# Aplicar filtros
|
|
filtered = leads
|
|
if search:
|
|
s = search.lower()
|
|
filtered = [l for l in filtered if s in l.get('nome_empresa', '').lower() or s in l.get('telefone', '').lower() or s in l.get('notas', '').lower()]
|
|
if status_sel != "Todos":
|
|
filtered = [l for l in filtered if l.get('status_funil') == status_sel]
|
|
if cidade_sel != "Todas":
|
|
filtered = [l for l in filtered if l.get('cidade') == cidade_sel]
|
|
if ramo_sel != "Todos":
|
|
filtered = [l for l in filtered if l.get('ramo_atividade') == ramo_sel]
|
|
|
|
st.write(f"**Exibindo {len(filtered)} leads de {len(leads)} totais.**")
|
|
|
|
if filtered:
|
|
rows = []
|
|
for l in filtered:
|
|
tel_san = l.get('telefone_sanitizado', '')
|
|
wa_link = f"https://wa.me/{tel_san}" if tel_san else ""
|
|
rows.append({
|
|
'ID': l.get('id'),
|
|
'Empresa': l.get('nome_empresa'),
|
|
'Ramo': l.get('ramo_atividade'),
|
|
'Cidade/UF': f"{l.get('cidade', '')}/{l.get('uf', '')}",
|
|
'Telefone': l.get('telefone'),
|
|
'Rating': f"⭐ {l.get('google_rating', 0.0)}",
|
|
'Status': l.get('status_funil'),
|
|
'WhatsApp': wa_link,
|
|
'Criado em': l.get('criado_em', '')[:10] if l.get('criado_em') else ''
|
|
})
|
|
|
|
df = pd.DataFrame(rows)
|
|
st.dataframe(
|
|
df,
|
|
column_config={
|
|
"WhatsApp": st.column_config.LinkColumn("WhatsApp Link", display_text="💬 Conversar")
|
|
},
|
|
use_container_width=True,
|
|
hide_index=True
|
|
)
|
|
|
|
st.markdown("### ⚙️ Ações Rápidas")
|
|
col_sel, col_act = st.columns([2, 1])
|
|
with col_sel:
|
|
selected_lead_id = st.selectbox(
|
|
"Selecione um Lead para Ação LGPD:",
|
|
options=[l['id'] for l in filtered],
|
|
format_func=lambda x: next((f"{l['nome_empresa']} ({l['status_funil']})" for l in filtered if l['id'] == x), x)
|
|
)
|
|
|
|
with col_act:
|
|
if st.button("🚫 Marcar Opt-Out (LGPD)", type="secondary", use_container_width=True):
|
|
if selected_lead_id:
|
|
api_client.opt_out_lead(selected_lead_id)
|
|
st.success("Lead marcado como Opt-Out (Excluído / LGPD).")
|
|
st.rerun()
|
|
else:
|
|
st.info("Nenhum lead encontrado com os filtros selecionados.")
|