-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadmin.html
More file actions
170 lines (156 loc) · 8.54 KB
/
admin.html
File metadata and controls
170 lines (156 loc) · 8.54 KB
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Usage dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-50 min-h-screen">
<!-- Header -->
<header class="bg-white shadow-sm sticky top-0 z-10">
<div class="mx-auto max-w-7xl px-4 py-4 sm:px-6 lg:px-8 flex justify-between items-center">
<div class="flex items-center space-x-3">
<div class="p-2 bg-indigo-100 rounded-lg">
<svg class="h-6 w-6 text-indigo-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg>
</div>
<h1 class="text-2xl font-bold tracking-tight text-gray-900">Usage Dashboard</h1>
</div>
<div class="flex items-center space-x-2 text-sm text-gray-500">
<svg class="h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span>Last updated: <span id="lastUpdate" class="font-medium"></span></span>
</div>
</div>
</header>
<!-- Main Content -->
<main class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
<!-- Stats Overview -->
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4 mb-8">
<!-- Total Users -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-blue-100 mr-4">
<svg class="h-6 w-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
</svg>
</div>
<div>
<h3 class="text-gray-500 text-sm font-medium">Total users</h3>
<p class="text-2xl font-bold text-gray-900" id="totalUsers">0</p>
</div>
</div>
</div>
<!-- Total Messages -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-purple-100 mr-4">
<svg class="h-6 w-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path>
</svg>
</div>
<div>
<h3 class="text-gray-500 text-sm font-medium">Total messages</h3>
<p class="text-2xl font-bold text-gray-900" id="totalMessages">0</p>
</div>
</div>
</div>
<!-- Average Messages -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-green-100 mr-4">
<svg class="h-6 w-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg>
</div>
<div>
<h3 class="text-gray-500 text-sm font-medium">Avg messages/user</h3>
<p class="text-2xl font-bold text-gray-900" id="avgMessages">0</p>
</div>
</div>
</div>
<!-- Active Countries -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-yellow-100 mr-4">
<svg class="h-6 w-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 21v-4m0 0V5a2 2 0 012-2h6.5l1 1H21l-3 6 3 6h-8.5l-1-1H5a2 2 0 00-2 2zm9-13.5V9"></path>
</svg>
</div>
<div>
<h3 class="text-gray-500 text-sm font-medium">Active Countries</h3>
<p class="text-2xl font-bold text-gray-900" id="activeCountries">0</p>
</div>
</div>
</div>
</div>
<!-- Users Table -->
<div class="bg-white rounded-lg shadow p-6">
<h2 class="text-xl font-semibold mb-4">User activity</h2>
<div class="overflow-x-auto">
<table id="usersTable" class="w-full border-collapse">
<thead>
<tr class="bg-gray-50 text-left">
<th class="px-6 py-3 border-b border-gray-200">Name</th>
<th class="px-6 py-3 border-b border-gray-200">Username</th>
<th class="px-6 py-3 border-b border-gray-200">Country</th>
<th class="px-6 py-3 border-b border-gray-200">Messages</th>
<th class="px-6 py-3 border-b border-gray-200">Last active</th>
</tr>
</thead>
<tbody id="tableBody"></tbody>
</table>
</div>
</div>
</main>
<!-- Scripts -->
<script>
const users = {{!user_data}}
document.addEventListener('DOMContentLoaded', () => {
updateLastUpdatedTime();
updateStats();
initTable();
});
function updateLastUpdatedTime() {
const lastUpdateElement = document.getElementById('lastUpdate');
if (lastUpdateElement) {
lastUpdateElement.textContent = new Date().toLocaleString();
}
}
function updateStats() {
const totalUsers = users.length;
const totalMessages = users.reduce((sum, user) => sum + user.messageCount, 0);
const avgMessages = totalUsers > 0 ? Math.round(totalMessages / totalUsers) : 0;
const activeCountries = new Set(users.map(u => u.languageCode)).size;
document.getElementById('totalUsers').textContent = totalUsers;
document.getElementById('totalMessages').textContent = totalMessages.toLocaleString();
document.getElementById('avgMessages').textContent = avgMessages;
document.getElementById('activeCountries').textContent = activeCountries;
}
function initTable() {
const tableBody = document.getElementById('tableBody');
tableBody.innerHTML = '';
users.forEach(user => {
const row = document.createElement('tr');
const lastActiveDate = new Date(user.lastMessageTime);
row.innerHTML = `
<td class="px-6 py-3 border-b border-gray-200">${user.firstName} ${user.lastName || ''}</td>
<td class="px-6 py-3 border-b border-gray-200 text-gray-600">@${user.userName}</td>
<td class="px-6 py-3 border-b border-gray-200">
<span class="px-2 py-1 bg-gray-100 text-gray-800 rounded-full text-xs font-medium">${user.languageCode.toUpperCase()}</span>
</td>
<td class="px-6 py-3 border-b border-gray-200 font-medium">${user.messageCount.toLocaleString()}</td>
<td class="px-6 py-3 border-b border-gray-200 text-sm">
<div class="text-gray-600">${lastActiveDate.toLocaleDateString()}</div>
<div class="text-gray-400 text-xs">${lastActiveDate.toLocaleTimeString()}</div>
</td>
`;
tableBody.appendChild(row);
});
}
</script>
</body>
</html>