ShelfPhotoAnalyzer / utils /ui_components.py
Marek4321's picture
Upload 9 files
af2bcb1 verified
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"""
<div style="
border: 2px solid {border_color};
border-radius: 10px;
padding: 15px;
margin: 10px 0;
background-color: white;
">
</div>
""", 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