"""Página de análises de tempo e movimentos do checklist""" import streamlit as st import pandas as pd import plotly.express as px import plotly.graph_objects as go from utils.database import get_checklist_analytics, get_checklist_with_items from datetime import datetime, timedelta st.set_page_config( page_title="Análises de Tempo", page_icon="📊", layout="wide" ) def format_time(seconds): """Formata segundos em formato legível""" if seconds is None or seconds == 0: return "0s" if seconds < 60: return f"{int(seconds)}s" elif seconds < 3600: minutes = int(seconds // 60) secs = int(seconds % 60) return f"{minutes}m {secs}s" else: hours = int(seconds // 3600) minutes = int((seconds % 3600) // 60) return f"{hours}h {minutes}m" def main(): if 'current_checklist_id' not in st.session_state or st.session_state.current_checklist_id is None: st.error("Nenhum checklist selecionado!") if st.button("← Voltar para Início"): st.switch_page("app.py") return checklist_id = st.session_state.current_checklist_id try: # Buscar dados do checklist checklist = get_checklist_with_items(checklist_id) analytics = get_checklist_analytics(checklist_id) if not checklist: st.error("Checklist não encontrado!") return # Header col1, col2 = st.columns([5, 1]) with col1: st.title(f"📊 Análises: {checklist['name']}") if checklist['numero_processo']: st.caption(f"🔢 Processo: {checklist['numero_processo']}") with col2: if st.button("← Voltar"): st.switch_page("pages/dashboard.py") st.markdown("---") # Estatísticas gerais stats = analytics['stats'] time_analysis = analytics['time_analysis'] if stats['first_interaction'] and stats['last_interaction']: total_time = stats['last_interaction'] - stats['first_interaction'] total_minutes = total_time.total_seconds() / 60 else: total_minutes = 0 col1, col2, col3, col4 = st.columns(4) with col1: st.metric("Total de Items", stats['total_items']) with col2: st.metric("Items Concluídos", stats['completed_items']) with col3: completion_rate = (stats['completed_items'] / stats['total_items']) * 100 if stats['total_items'] > 0 else 0 st.metric("Taxa de Conclusão", f"{completion_rate:.1f}%") with col4: st.metric("Tempo Total", format_time(total_minutes * 60)) st.markdown("---") # Análise por item if time_analysis: st.markdown("### 📈 Análise de Tempo por Item") # Criar DataFrame para visualização df_time = pd.DataFrame(time_analysis) # Converter colunas para tipos numéricos corretos df_time['total_seconds_spent'] = pd.to_numeric(df_time['total_seconds_spent'], errors='coerce').fillna(0) df_time['avg_seconds_per_completion'] = pd.to_numeric(df_time['avg_seconds_per_completion'], errors='coerce').fillna(0) df_time['times_worked'] = pd.to_numeric(df_time['times_worked'], errors='coerce').fillna(0).astype(int) df_time['tempo_formatado'] = df_time['total_seconds_spent'].apply(lambda x: format_time(x) if x else "0s") df_time['tempo_medio_formatado'] = df_time['avg_seconds_per_completion'].apply(lambda x: format_time(x) if x else "0s") df_time['vezes_trabalhado'] = df_time['times_worked'] # Gráfico de barras - Tempo total por item if not df_time.empty and df_time['total_seconds_spent'].sum() > 0: fig_time = px.bar( df_time.sort_values('total_seconds_spent', ascending=False), x='item_text', y='total_seconds_spent', title="Tempo Total Gasto por Item", labels={'total_seconds_spent': 'Tempo (segundos)', 'item_text': 'Item'} ) fig_time.update_layout(xaxis_tickangle=-45) st.plotly_chart(fig_time, use_container_width=True) # Gráfico de pizza - Distribuição do tempo df_positive = df_time[df_time['total_seconds_spent'] > 0] if not df_positive.empty: fig_pie = px.pie( df_positive, values='total_seconds_spent', names='item_text', title="Distribuição do Tempo por Item" ) st.plotly_chart(fig_pie, use_container_width=True) # Tabela detalhada st.markdown("### 📋 Detalhes por Item") df_display = df_time[['item_text', 'vezes_trabalhado', 'tempo_formatado', 'tempo_medio_formatado']].copy() df_display.columns = ['Item', 'Vezes Trabalhado', 'Tempo Total', 'Tempo Médio'] # Ordenar pela coluna numérica original df_display = df_display.loc[df_time.sort_values('total_seconds_spent', ascending=False).index] st.dataframe(df_display, use_container_width=True) # Insights automáticos st.markdown("### 🔍 Insights") col1, col2 = st.columns(2) with col1: st.markdown("#### Items mais demorados") if not df_time.empty and df_time['total_seconds_spent'].sum() > 0: top_slow = df_time.sort_values('total_seconds_spent', ascending=False).head(3) for _, item in top_slow.iterrows(): if item['total_seconds_spent'] > 0: st.write(f"• **{item['item_text']}**: {item['tempo_formatado']}") else: st.info("Nenhum dado de tempo disponível ainda.") with col2: st.markdown("#### Items mais retrabalhados") if not df_time.empty and df_time['times_worked'].sum() > 0: top_rework = df_time.sort_values('times_worked', ascending=False).head(3) for _, item in top_rework.iterrows(): if item['times_worked'] > 1: st.write(f"• **{item['item_text']}**: {item['times_worked']} vezes") else: st.info("Nenhum retrabalho identificado.") # Recomendações st.markdown("#### 💡 Recomendações") if not df_time.empty and df_time['total_seconds_spent'].sum() > 0: mean_time = df_time['total_seconds_spent'].mean() slow_items = df_time[df_time['total_seconds_spent'] > mean_time]['item_text'].tolist() rework_items = df_time[df_time['times_worked'] > 1]['item_text'].tolist() if slow_items: st.warning(f"**Items que demandam mais tempo:** {', '.join(slow_items[:3])}") st.write("💡 Considere revisar estes items ou dividir em subtarefas menores.") if rework_items: st.info(f"**Items com retrabalho:** {', '.join(rework_items[:3])}") st.write("💡 Analise se estes items precisam de mais clareza ou recursos adicionais.") if not slow_items and not rework_items: st.success("✅ Ótimo trabalho! O checklist está sendo executado de forma eficiente.") elif not df_time.empty: st.info("📊 Marque e desmarque alguns items para gerar recomendações baseadas no tempo de execução.") else: st.info("📊 Ainda não há dados suficientes para análise. Continue marcando os items do checklist para gerar insights.") # Mostrar checklist atual st.markdown("### 📋 Status Atual dos Items") for item in checklist['items']: status = "✅" if item['is_checked'] else "⏳" st.write(f"{status} {item['text']}") except Exception as e: st.error(f"Erro ao carregar análises: {str(e)}") if st.button("← Voltar para Dashboard"): st.switch_page("pages/dashboard.py") if __name__ == "__main__": main()