import streamlit as st from typing import Dict, List from utils.recommendations import calculate_total_impact def display_results(analysis_results: Dict, product_name: str): """Display analysis results in a formatted way""" col1, col2, col3 = st.columns(3) with col1: # Overall score score = analysis_results.get('overall_score', 5) if score >= 8: score_color = "🟢" score_text = "Excellent" elif score >= 6: score_color = "🟡" score_text = "Good" else: score_color = "🔴" score_text = "Needs Improvement" st.metric( label="Overall Score", value=f"{score}/10", delta=score_text, help="Overall assessment of product placement" ) with col2: # Confidence confidence = analysis_results.get('confidence', 0.5) confidence_pct = int(confidence * 100) st.metric( label="AI Confidence", value=f"{confidence_pct}%", help="How confident the AI is in this analysis" ) with col3: # Product found status found = analysis_results.get('product_found', False) status = "✅ Found" if found else "❌ Not Found" st.metric( label="Product Status", value=status, help="Whether the product was detected on the shelf" ) st.markdown("---") # Detailed information col1, col2 = st.columns(2) with col1: st.markdown("### 📊 Product Details") # Facing count facing_count = analysis_results.get('facing_count', 0) st.info(f"**Facings:** {facing_count} visible units") # Shelf position position = analysis_results.get('shelf_position', 'Unknown') position_emoji = { 'top': '⬆️', 'middle': '➡️', 'bottom': '⬇️', 'górna': '⬆️', 'środkowa': '➡️', 'dolna': '⬇️' }.get(position.lower(), '❓') st.info(f"**Position:** {position_emoji} {position.title()}") # Price visibility price_visible = analysis_results.get('price_visible', False) price_status = "✅ Visible" if price_visible else "❌ Not visible" st.info(f"**Price:** {price_status}") with col2: st.markdown("### 🔍 Quality Assessment") # Product condition condition = analysis_results.get('product_condition', 'Unknown') condition_emoji = { 'good': '✅', 'dusty': '🧹', 'damaged': '⚠️', 'dobry': '✅', 'zakurzony': '🧹', 'uszkodzony': '⚠️' }.get(condition.lower(), '❓') st.info(f"**Condition:** {condition_emoji} {condition.title()}") # Shelf share shelf_share = analysis_results.get('shelf_share', 0) if shelf_share > 0: st.info(f"**Shelf Share:** {shelf_share}% of shelf space") # Competitors competitors = analysis_results.get('competitors_nearby', []) if competitors: st.info(f"**Nearby Competitors:** {len(competitors)} products") # Description description = analysis_results.get('description', '') if description: st.markdown("### 📝 Analysis Details") st.markdown(f"> {description}") def display_recommendations(recommendations: List[Dict]): """Display recommendations in a formatted way""" if not recommendations: st.info("No specific recommendations generated.") return # Calculate total impact impact_summary = calculate_total_impact(recommendations) # Display summary metrics col1, col2, col3, col4 = st.columns(4) with col1: st.metric( "Total Recommendations", impact_summary['total_recommendations'], help="Number of actionable recommendations" ) with col2: st.metric( "High Priority", impact_summary['high_priority_count'], help="Critical issues requiring immediate attention" ) with col3: st.metric( "Estimated Time", f"{impact_summary['total_time_minutes']} min", help="Total time needed to implement all changes" ) with col4: # Calculate difficulty distribution difficulties = [r.get('difficulty', 'Unknown') for r in recommendations] easy_count = difficulties.count('Bardzo łatwe') + difficulties.count('Łatwe') difficulty_text = f"{easy_count}/{len(recommendations)} Easy" st.metric( "Difficulty", difficulty_text, help="How many recommendations are easy to implement" ) st.markdown("---") # Group recommendations by priority high_priority = [r for r in recommendations if r.get('priority', 5) <= 2] medium_priority = [r for r in recommendations if r.get('priority', 5) == 3] low_priority = [r for r in recommendations if r.get('priority', 5) >= 4] # Display high priority recommendations if high_priority: st.markdown("### 🚨 High Priority (Do First)") for rec in high_priority: display_recommendation_card(rec) # Display medium priority recommendations if medium_priority: st.markdown("### ⚡ Medium Priority") for rec in medium_priority: display_recommendation_card(rec) # Display low priority recommendations if low_priority: st.markdown("### 💡 Additional Improvements") for rec in low_priority: display_recommendation_card(rec) def display_recommendation_card(recommendation: Dict): """Display a single recommendation as a card""" # Priority styling priority = recommendation.get('priority', 5) if priority <= 2: border_color = "#ff4b4b" # Red elif priority == 3: border_color = "#ffa500" # Orange else: border_color = "#1f77b4" # Blue # Card styling st.markdown(f"""
""", unsafe_allow_html=True) with st.container(): col1, col2 = st.columns([3, 1]) with col1: # Title and description title = recommendation.get('title', 'Recommendation') st.markdown(f"**{title}**") description = recommendation.get('description', '') if description: st.markdown(f"*{description}*") # Action action = recommendation.get('action', '') if action: st.markdown(f"**Action:** {action}") with col2: # Metrics impact = recommendation.get('estimated_impact', '') if impact: st.markdown(f"📈 **{impact}**") time_to_fix = recommendation.get('time_to_fix', '') if time_to_fix: st.markdown(f"⏱️ {time_to_fix}") difficulty = recommendation.get('difficulty', '') if difficulty: difficulty_emoji = { 'Bardzo łatwe': '🟢', 'Łatwe': '🟡', 'Średnie': '🟠', 'Trudne': '🔴' }.get(difficulty, '⚪') st.markdown(f"{difficulty_emoji} {difficulty}") def display_analysis_history(history: List[Dict]): """Display analysis history""" if not history: st.info("No analysis history available.") return for i, analysis in enumerate(reversed(history[-10:])): # Show last 10 with st.expander( f"{analysis.get('product_name', 'Unknown')} - {analysis.get('analysis_date', 'Unknown')}" ): results = analysis.get('results', {}) col1, col2, col3 = st.columns(3) with col1: score = results.get('overall_score', 'N/A') st.metric("Score", f"{score}/10") with col2: found = results.get('product_found', False) status = "Found" if found else "Not Found" st.metric("Status", status) with col3: facings = results.get('facing_count', 0) st.metric("Facings", facings) description = results.get('description', '') if description: st.markdown(f"**Description:** {description[:200]}...") def create_export_summary(analysis_results: Dict, recommendations: List[Dict], product_name: str) -> str: """Create a summary for export purposes""" summary = f""" # Shelf Analysis Report - {product_name} ## Analysis Results - **Overall Score:** {analysis_results.get('overall_score', 'N/A')}/10 - **Product Found:** {'Yes' if analysis_results.get('product_found') else 'No'} - **Facing Count:** {analysis_results.get('facing_count', 0)} - **Shelf Position:** {analysis_results.get('shelf_position', 'Unknown')} - **Price Visible:** {'Yes' if analysis_results.get('price_visible') else 'No'} - **Product Condition:** {analysis_results.get('product_condition', 'Unknown')} - **AI Confidence:** {int(analysis_results.get('confidence', 0.5) * 100)}% ## Recommendations ({len(recommendations)}) """ for i, rec in enumerate(recommendations, 1): summary += f""" ### {i}. {rec.get('title', 'Recommendation')} - **Priority:** {rec.get('priority', 'N/A')} - **Description:** {rec.get('description', '')} - **Action:** {rec.get('action', '')} - **Estimated Impact:** {rec.get('estimated_impact', '')} - **Time to Fix:** {rec.get('time_to_fix', '')} - **Difficulty:** {rec.get('difficulty', '')} """ return summary