File size: 6,359 Bytes
b5f41c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>NEXUS - Centre de Commandement</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap" rel="stylesheet">
    <style>

        body { font-family: 'Inter', sans-serif; background-color: #0f172a; color: #f8fafc; }

        .glass-panel { background: rgba(30, 41, 59, 0.7); backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.1); }

    </style>
</head>
<body class="min-h-screen p-6">

    <header class="flex justify-between items-center mb-8 border-b border-slate-700 pb-4">
        <div>
            <h1 class="text-3xl font-extrabold text-blue-400 tracking-tight">NEXUS PRIME</h1>
            <p class="text-slate-400 text-sm">Centre de Commandement & Dispatching</p>
        </div>
        <div class="flex items-center gap-3">
            <div class="h-3 w-3 bg-green-500 rounded-full animate-pulse"></div>
            <span class="text-sm font-semibold text-slate-300">Système En Ligne</span>
        </div>
    </header>

    <main>
        <div class="glass-panel rounded-xl overflow-hidden shadow-2xl">
            <div class="p-4 bg-slate-800 border-b border-slate-700">
                <h2 class="text-lg font-semibold flex items-center gap-2">
                    📡 File d'attente des urgences en direct
                </h2>
            </div>
            
            <div class="overflow-x-auto">
                <table class="w-full text-left text-sm">
                    <thead class="bg-slate-900 text-slate-400">
                        <tr>
                            <th class="p-4 font-semibold">Heure</th>
                            <th class="p-4 font-semibold">Téléphone</th>
                            <th class="p-4 font-semibold w-1/3">Message du Citoyen</th>
                            <th class="p-4 font-semibold">Analyse IA</th>
                            <th class="p-4 font-semibold">Action / Dispatch</th>
                        </tr>
                    </thead>
                    <tbody id="tickets-body" class="divide-y divide-slate-700/50">
                        <!-- Les tickets apparaitront ici -->
                        <tr>
                            <td colspan="5" class="p-8 text-center text-slate-500 italic">En attente de signalements WhatsApp...</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </main>

    <script>

        // Correction : L'adresse IP GCP unifiée pour tout le projet

        const API_BASE_URL = "http://35.199.168.248:7860";



        async function fetchTickets() {

            try {

                const response = await fetch(`${API_BASE_URL}/api/tickets`);

                const tickets = await response.json();

                renderTickets(tickets);

            } catch (error) {

                console.error("Erreur de connexion au serveur NEXUS:", error);

            }

        }



        function renderTickets(tickets) {

            const tbody = document.getElementById('tickets-body');

            if (tickets.length === 0) return;

            tbody.innerHTML = ''; 

            

            tickets.forEach(ticket => {

                const tr = document.createElement('tr');

                tr.className = "hover:bg-slate-800/50 transition-colors";

                

                let iaColor = "text-slate-400";

                if(ticket.domaine_ia === "POLICE") iaColor = "text-blue-400 font-bold";

                if(ticket.domaine_ia === "POMPIERS") iaColor = "text-red-400 font-bold";

                if(ticket.domaine_ia === "SAMU") iaColor = "text-emerald-400 font-bold";



                const isTransferred = ticket.status.includes("TRANSFÉRÉ");

                

                tr.innerHTML = `

                    <td class="p-4 text-slate-300 font-mono">${ticket.heure}</td>

                    <td class="p-4 font-semibold text-slate-200">${ticket.telephone}</td>

                    <td class="p-4 text-slate-300">${ticket.message}</td>

                    <td class="p-4 ${iaColor}">

                        ${ticket.domaine_ia} 

                        ${ticket.score > 0 ? `<span class="bg-slate-700 text-xs px-2 py-1 rounded ml-2">Score: ${ticket.score}/10</span>` : ''}

                    </td>

                    <td class="p-4">

                        ${isTransferred ? 

                            `<span class="text-green-400 font-semibold text-xs border border-green-500/30 bg-green-500/10 px-3 py-1.5 rounded-full">${ticket.status}</span>` 

                            : 

                            `<div class="flex gap-2">

                                <button onclick="dispatchTicket(${ticket.id}, 'POLICE')" class="bg-blue-600 hover:bg-blue-500 text-white text-xs font-bold py-1.5 px-3 rounded shadow transition-all">POLICE</button>

                                <button onclick="dispatchTicket(${ticket.id}, 'POMPIERS')" class="bg-red-600 hover:bg-red-500 text-white text-xs font-bold py-1.5 px-3 rounded shadow transition-all">POMPIERS</button>

                                <button onclick="dispatchTicket(${ticket.id}, 'SAMU')" class="bg-emerald-600 hover:bg-emerald-500 text-white text-xs font-bold py-1.5 px-3 rounded shadow transition-all">SAMU</button>

                            </div>`

                        }

                    </td>

                `;

                tbody.appendChild(tr);

            });

        }



        async function dispatchTicket(ticketId, serviceName) {

            try {

                await fetch(`${API_BASE_URL}/api/tickets/${ticketId}/dispatch`, {

                    method: 'POST',

                    headers: { 'Content-Type': 'application/json' },

                    body: JSON.stringify({ service: serviceName })

                });

                fetchTickets();

            } catch (error) {

                alert("Erreur lors de la transmission aux services.");

            }

        }



        setInterval(fetchTickets, 2000);

        fetchTickets(); 

    </script>
</body>
</html>