File size: 5,536 Bytes
67bf425
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
app.py β€” Main Streamlit entry point for No-CelH Self-Learning RMS
Run: streamlit run app.py
Hugging Face Spaces: set SDK=streamlit, app_file=app.py
"""

import streamlit as st

st.set_page_config(
    page_title="No-CelH Β· Self-Learning RMS",
    page_icon="πŸ›ƒ",
    layout="wide",
    initial_sidebar_state="expanded",
    menu_items={
        "Get Help":    "https://www.wcoomd.org/en/topics/enforcement-and-compliance/activities-and-programmes/risk-management.aspx",
        "Report a bug": None,
        "About":        "No-CelH: Self-Learning RMS β€” WCO Accredited Expert Simulation Tool\n\nBuilt on DATE + gATE Active Learning (Kim et al. 2022, IEEE TKDE)",
    },
)

import page1_intro
import page2_risk_register
import page3_simulation
import page4_results
import page5_optimisation
from styles import WCO_GOLD, WCO_NAVY, WCO_BORDER, WCO_CARD_BG, WCO_MUTED, WCO_RED, WCO_GREEN

PAGES = {
    "🏠  Introduction & Architecture": page1_intro,
    "πŸ“‹  Risk Register & Matrix":      page2_risk_register,
    "πŸ”„  Simulation Engine":           page3_simulation,
    "πŸ“Š  Simulation Results":          page4_results,
    "πŸ†  Bandwidth Optimisation":      page5_optimisation,
}

def sidebar():
    with st.sidebar:
        st.markdown(f"""
        <div style="text-align:center;padding:20px 10px 14px;">
          <div style="font-size:42px;">πŸ›ƒ</div>
          <div style="color:{WCO_GOLD};font-family:'Playfair Display',Georgia,serif;
                      font-size:16px;font-weight:700;margin-top:8px;line-height:1.3;">
            No-CelH<br/>Self-Learning RMS
          </div>
          <div style="color:{WCO_MUTED};font-size:10px;margin-top:6px;
                      font-family:'IBM Plex Mono',monospace;letter-spacing:0.06em;">
            WCO ACCREDITED Β· v2.0
          </div>
        </div>
        <hr style="border-color:{WCO_BORDER};margin:0 0 16px;"/>
        """, unsafe_allow_html=True)

        st.markdown(f"""
        <div style="color:{WCO_GOLD};font-size:11px;font-weight:600;
                    letter-spacing:0.1em;text-transform:uppercase;
                    padding:0 4px;margin-bottom:8px;">Navigation</div>
        """, unsafe_allow_html=True)

        selected = st.radio("", list(PAGES.keys()),
                            key="nav_page", label_visibility="collapsed")

        st.markdown(f"<hr style='border-color:{WCO_BORDER};margin:16px 0;'/>",
                    unsafe_allow_html=True)

        # Session state status panel
        sim_ready = "sim_df" in st.session_state
        st.markdown(f"""
        <div style="background:{WCO_CARD_BG};border:1px solid {WCO_BORDER};
                    border-radius:10px;padding:14px;">
          <div style="color:{WCO_GOLD};font-size:11px;font-weight:600;
                      text-transform:uppercase;letter-spacing:0.08em;margin-bottom:10px;">
            Session Status
          </div>
          <div style="font-size:12px;line-height:2.1;color:#8BAAD4;">
            <span style="color:{'#44CC88' if sim_ready else WCO_MUTED};">
              {'βœ…' if sim_ready else '⬜'}</span>  Simulation Run<br/>
            <span style="color:{'#44CC88' if 'rule_weights' in st.session_state else WCO_MUTED};">
              {'βœ…' if 'rule_weights' in st.session_state else '⬜'}</span>  Weights Configured<br/>
            <span style="color:{'#44CC88' if 'sim_efficiency' in st.session_state else WCO_MUTED};">
              {'βœ…' if 'sim_efficiency' in st.session_state else '⬜'}</span>  Results Available
          </div>
        </div>
        """, unsafe_allow_html=True)

        if sim_ready:
            df = st.session_state.sim_df
            eff = st.session_state.get("sim_efficiency", {}).get("hybrid", {})
            st.markdown(f"""
            <div style="background:{WCO_CARD_BG};border:1px solid {WCO_BORDER};
                        border-radius:10px;padding:14px;margin-top:10px;">
              <div style="color:{WCO_GOLD};font-size:11px;font-weight:600;
                          text-transform:uppercase;letter-spacing:0.08em;margin-bottom:10px;">
                Last Simulation
              </div>
              <div style="font-size:12px;line-height:2.1;color:#8BAAD4;">
                πŸ“¦ Bills: <b style="color:#D0DCF0;">{len(df):,}</b><br/>
                πŸ”΄ RED: <b style="color:{WCO_RED};">{(df['channel']=='RED').sum()}</b><br/>
                🟑 YEL: <b style="color:{WCO_GOLD};">{(df['channel']=='YELLOW').sum()}</b><br/>
                🟒 GRN: <b style="color:{WCO_GREEN};">{(df['channel']=='GREEN').sum()}</b><br/>
                🚨 Detected: <b style="color:{WCO_RED};">
                  {(df['inspection_outcome']=='FRAUD_DETECTED').sum()}</b><br/>
                πŸ“ˆ Efficiency: <b style="color:{WCO_GREEN};">
                  {eff.get('efficiency_index',0):.3f}</b>
              </div>
            </div>
            """, unsafe_allow_html=True)

        st.markdown(f"""
        <hr style="border-color:{WCO_BORDER};margin:16px 0 10px;"/>
        <div style="color:{WCO_MUTED};font-size:10px;text-align:center;line-height:1.7;padding:0 4px;">
          Based on: Kim et al. (2022)<br/>
          <i>Active Learning for Human-in-the-Loop Customs Inspection</i><br/>
          IEEE TKDE Β· WCO Compendium<br/>
          <span style="color:{WCO_GOLD};">WCO BACUDA Initiative</span>
        </div>
        """, unsafe_allow_html=True)

    return selected


def main():
    selected = sidebar()
    PAGES[selected].show()


if __name__ == "__main__":
    main()