File size: 7,348 Bytes
76d67c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e0feda0
 
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
import gradio as gr
from claims_agent import ClaimsIntakeAgent
from adjuster_dashboard import AdjusterDashboard
from utils import extract_claim_data
from PIL import Image

# Initialize Agents and Dashboard
intake_agent = ClaimsIntakeAgent()
dashboard = AdjusterDashboard()

# --- Claims Intake View Functions ---
import time

# --- Claims Intake View Functions ---
def intake_chat(message, image, file, progress=gr.Progress()):
    # Yield status updates to the output box directly
    yield "πŸ”„ **Initializing AI Agent...**"
    progress(0.1, desc="Initializing AI Agent...")
    time.sleep(0.5) # Simulate init time
    
    yield "πŸ” **Analyzing Image & Documents...**"
    progress(0.3, desc="Analyzing Image & Documents...")
    # If file is provided, it comes as a filepath
    response = intake_agent.process_claim(message, image, file)
    
    yield "πŸ’Ύ **Syncing with Adjuster Dashboard...**"
    progress(0.7, desc="Syncing with Adjuster Dashboard...")
    # Sync with Dashboard
    if response and "Error" not in response:
        try:
            claim_data = extract_claim_data(response)
            # Update the dashboard data
            # Note: In a real app with concurrent users, this needs better state management.
            # Here we update the global dashboard object.
            dashboard.add_claim(claim_data)
        except Exception as e:
            print(f"Error syncing to dashboard: {e}")
            
    progress(1.0, desc="Assessment Complete!")
    yield response

# --- Adjuster Auth Functions ---
def check_password(password):
    if password == "password":
        return gr.update(visible=False), gr.update(visible=True)
    return gr.update(visible=True), gr.update(visible=False)

# --- UI Construction ---
custom_css = """
#main_container {
    max-width: 1000px;
    margin: 0 auto;
    padding: 20px;
    background-color: white;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    margin-top: 20px;
}
body {
    background-color: #f0f2f5;
}
h1 {
    text-align: center;
    color: #2c3e50;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
"""

with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="slate"), title="EMA Claims MVP", css=custom_css) as demo:
    with gr.Column(elem_id="main_container"):
        gr.Markdown("# πŸ›‘οΈ EMA Claims MVP")
        
        with gr.Tabs():
            # Tab 1: Customer View (Claims Intake)
            with gr.Tab("πŸš— Claims Intake (Customer)"):
                gr.Markdown("### Report an Accident")
                gr.Markdown("Upload a photo of the damage and any relevant documents (PDF/Doc). Our AI will assess it immediately.")
                
                with gr.Row():
                    with gr.Column(scale=1):
                        image_input = gr.Image(type="pil", label="Upload Damage Photo")
                        file_input = gr.File(label="Upload Documents (PDF/Doc)", file_types=[".pdf", ".docx", ".txt"])
                        msg_input = gr.Textbox(placeholder="Describe the accident...", label="Description")
                        submit_btn = gr.Button("Submit Claim", variant="primary")
                    
                    with gr.Column(scale=1):
                        chat_output = gr.Markdown(label="AI Assessment")
                
                # We need to update the claims table if it's visible, but since it's in another tab, 
                # we can rely on the global dashboard object being updated. 
                # However, Gradio components need an event to refresh.
                # For MVP, we'll just update the global list. The table in the other tab won't auto-refresh 
                # without a trigger, but we can add a "Refresh" button or make the table update on tab select (harder in simple Blocks).
                # Let's add a "Refresh" button to the dashboard.
                
                submit_btn.click(
                    fn=intake_chat,
                    inputs=[msg_input, image_input, file_input], 
                    outputs=[chat_output],
                    show_progress=True
                )

            # Tab 2: Adjuster View (Dashboard)
            with gr.Tab("πŸ‘¨β€πŸ’Ό Adjuster Dashboard (Internal)"):
                
                # Login State
                with gr.Group(visible=True) as login_group:
                    gr.Markdown("### Internal Access Only")
                    password_input = gr.Textbox(label="Password", type="password")
                    login_btn = gr.Button("Login")
                
                # Dashboard Content (Hidden by default)
                with gr.Group(visible=False) as dashboard_group:
                    gr.Markdown("### Incoming Claims Queue")
                    refresh_btn = gr.Button("Refresh List", size="sm")
                    
                    with gr.Row():
                        with gr.Column(scale=2):
                            # Dataframe for claims list
                            claims_df = gr.Dataframe(
                                headers=["ID", "Submitter", "Date", "Vehicle", "Status", "Fraud Risk", "Classification"],
                                value=dashboard.get_claims_data, # Pass method to call on load/refresh
                                interactive=False,
                                label="Active Claims",
                                elem_id="claims_table"
                            )
                        
                        with gr.Column(scale=1):
                            # Details Panel
                            details_panel = gr.Markdown("Select a claim to view details.", label="Claim Analysis")
                            with gr.Row():
                                approve_btn = gr.Button("Approve Payment", variant="primary", interactive=False)
                                escalate_btn = gr.Button("Escalate to SIU", variant="stop", interactive=False)
                            
                            action_output = gr.Label(label="Action Status")

                    # Interactions
                    claims_df.select(
                        fn=dashboard.get_claim_details,
                        inputs=None,
                        outputs=[details_panel, approve_btn, escalate_btn]
                    )
                    
                    approve_btn.click(
                        fn=dashboard.approve_claim,
                        inputs=[details_panel],
                        outputs=[action_output]
                    )
                    
                    escalate_btn.click(
                        fn=dashboard.escalate_claim,
                        inputs=[details_panel],
                        outputs=[action_output]
                    )
                    
                    refresh_btn.click(
                        fn=lambda: dashboard.get_claims_data(),
                        inputs=None,
                        outputs=[claims_df]
                    )

                login_btn.click(
                    fn=check_password,
                    inputs=[password_input],
                    outputs=[login_group, dashboard_group]
                )

if __name__ == "__main__":
    demo.queue()
    demo.launch(server_name="0.0.0.0",   # not 127.0.0.1
    server_port=7860,)