File size: 8,803 Bytes
d54ba19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
"""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()