File size: 6,402 Bytes
9bc1376
 
efe8b67
9bc1376
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3a70dec
9bc1376
 
 
 
 
 
 
3a70dec
9bc1376
 
 
 
 
 
 
 
 
 
3a70dec
9bc1376
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3a70dec
9bc1376
 
 
 
 
efe8b67
 
9bc1376
 
efe8b67
9bc1376
 
3a70dec
9bc1376
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
import json, pandas as pd, streamlit as st
from typing import Dict, Any
from helpers_function.helpers import _mean_effectiveness

def _normalize_list(v):
    if v is None: return []
    if isinstance(v, list): return [str(x) for x in v]
    return [s for s in str(v).splitlines() if s.strip()]

def _to_dataframe(items, columns_map):
    import pandas as pd
    if not isinstance(items, list) or not items:
        return pd.DataFrame(columns=list(columns_map.values()))
    df = pd.DataFrame(items).rename(columns=columns_map)
    ordered_cols = [columns_map[k] for k in columns_map.keys() if columns_map[k] in df.columns]
    return df.reindex(columns=ordered_cols)


def _search_dataframe(df, query):
    if not query or df.empty: return df
    mask = df.apply(lambda col: col.astype(str).str.contains(query, case=False, na=False))
    return df[mask.any(axis=1)]

def render_analyzer_results(analysis: Dict[str, Any]) -> None:
    if not isinstance(analysis, dict) or not analysis:
        st.warning("No analysis available."); return

    st.markdown(
        """<style>
        .metric-card{background:#0f172a;padding:14px 16px;border-radius:14px;border:1px solid #1f2937}
        .label{font-size:12px;color:#94a3b8;margin-bottom:6px}
        .value{font-size:16px;color:#e2e8f0}
        </style>""",
        unsafe_allow_html=True,
    )
    va = analysis.get("video_analysis", {}) or {}
    storyboard = analysis.get("storyboard", []) or []
    script = analysis.get("script", []) or []
    metrics = va.get("video_metrics", []) or []
    mean_score = _mean_effectiveness(metrics)

    m1,m2,m3,m4 = st.columns([1,1,1,1])
    m1.markdown(f'<div class="metric-card"><div class="label">Scenes</div><div class="value">{len(storyboard)}</div></div>', unsafe_allow_html=True)
    m2.markdown(f'<div class="metric-card"><div class="label">Dialogue Lines</div><div class="value">{len(script)}</div></div>', unsafe_allow_html=True)
    m3.markdown(f'<div class="metric-card"><div class="label">Avg Effectiveness</div><div class="value">{mean_score}/10</div></div>', unsafe_allow_html=True)
    m4.markdown(f'<div class="metric-card"><div class="label">Improvements</div><div class="value">{len(analysis.get("timestamp_improvements", []) or [])}</div></div>', unsafe_allow_html=True)

    colA, colB = st.columns([1.3,1])
    with colA:
        st.markdown("### Executive Summary")
        c1,c2 = st.columns(2)
        with c1:
            with st.expander("Brief", expanded=True): st.write(analysis.get("brief", "N/A"))
            with st.expander("Caption Details", expanded=False): st.write(analysis.get("caption_details", "N/A"))
        with c2:
            hook = analysis.get("hook", {}) or {}
            with st.expander("Hook", expanded=True):
                st.markdown(f"**Opening:** {hook.get('hook_text','N/A')}")
                st.markdown(f"**Principle:** {hook.get('principle','N/A')}")
                adv = _normalize_list(hook.get("advantages"))
                if adv:
                    st.markdown("**Advantages:**")
                    st.markdown("\n".join([f"- {a}" for a in adv]))
        st.divider()
        st.markdown("### Narrative & Copy Frameworks")
        with st.expander("Framework Analysis", expanded=True): st.write(analysis.get("framework_analysis", "N/A"))
    with colB:
        st.markdown("### Snapshot")
        st.caption("Top Drivers"); st.markdown(f'{va.get("effectiveness_factors","N/A")}</div>', unsafe_allow_html=True)
        st.markdown(""); st.caption("Psychological Triggers"); st.markdown(f'{va.get("psychological_triggers","N/A")}</div>', unsafe_allow_html=True)
        st.markdown(""); st.caption("Target Audience"); st.markdown(f'{va.get("target_audience","N/A")}</div>', unsafe_allow_html=True)

    st.divider()
    tabs = st.tabs(["Storyboard","Script","Scored Metrics","Improvements","Raw JSON"])

    with tabs[0]:
        q = st.text_input("Search storyboard")
        if storyboard:
            df = _to_dataframe(
                storyboard,
                {"timeline":"Timeline","scene":"Scene","visuals":"Visuals","dialogue":"Dialogue","camera":"Camera","sound_effects":"Sound Effects"}
            )
            st.dataframe(_search_dataframe(df, q), width='stretch', height=480)
        else:
            st.info("No storyboard available.")

    with tabs[1]:
        q2 = st.text_input("Search script")
        if script:
            df = _to_dataframe(script, {"timeline":"Timeline","dialogue":"Dialogue"})
            st.dataframe(_search_dataframe(df, q2), width='stretch', height=480)
        else:
            st.info("No script breakdown available.")

    with tabs[2]:
        q3 = st.text_input("Search metrics")
        if metrics:
            dfm = _to_dataframe(
                metrics,
                {"timestamp":"Timestamp","element":"Element","current_approach":"Current Approach","effectiveness_score":"Effectiveness Score","notes":"Notes"}
            )
            st.dataframe(_search_dataframe(dfm, q3), width='stretch', height=480)
        else:
            st.info("No video metrics available.")

    with tabs[3]:
        improvements = analysis.get("timestamp_improvements", []) or []
        q4 = st.text_input("Search improvements")
        if improvements:
            imp_df = _to_dataframe(
                improvements,
                {"timestamp":"Timestamp","current_element":"Current Element","improvement_type":"Improvement Type",
                 "recommended_change":"Recommended Change","expected_impact":"Expected Impact","priority":"Priority"}
            )
            if "Priority" in imp_df.columns:
                order = pd.CategoricalDtype(["High","Medium","Low"], ordered=True)
                imp_df["Priority"] = imp_df["Priority"].astype(order)
                if "Timestamp" in imp_df.columns:
                    imp_df = imp_df.sort_values(["Priority","Timestamp"])
            st.dataframe(_search_dataframe(imp_df, q4), width='stretch', height=480)
        else:
            st.info("No timestamp-based improvements available.")


    with tabs[4]:
        res = json.dumps(analysis, indent=2, ensure_ascii=False)
        st.code(res, language="json")
        st.download_button(
            "Download JSON",
            data=res.encode("utf-8"),
            file_name="ad_analysis.json",
            mime="application/json",
            width='stretch'
        )