8 $initialData = [
9 'settings' => [
10 'site_name' => 'My Website',
11 'admin_password' => hash('sha256', 'admin123'),
12 'timezone' => 'UTC'
13 ],
14 'visitors' => [],
15 'pages' => []
16 ];
17 file_put_contents('stats.json', json_encode($initialData, JSON_PRETTY_PRINT));
18 }
19}
20
21// Log visitor
22function logVisitor($page = 'Home') {
23 $ip = $_SERVER['REMOTE_ADDR'];
24 $userAgent = $_SERVER['HTTP_USER_AGENT'];
25 $referrer = $_SERVER['HTTP_REFERER'] ?? 'Direct';
26 $timestamp = date('Y-m-d H:i:s');
27
28 // Get geolocation
29 $geo = getGeolocation($ip);
30
31 $visitorData = [
32 'ip' => $ip,
33 'user_agent' => $userAgent,
34 'referrer' => $referrer,
35 'timestamp' => $timestamp,
36 'page' => $page,
37 'country' => $geo['country'] ?? 'Unknown',
38 'city' => $geo['city'] ?? 'Unknown',
39 'region' => $geo['region'] ?? 'Unknown'
40 ];
41
42 $stats = json_decode(file_get_contents('stats.json'), true);
43 array_unshift($stats['visitors'], $visitorData);
44
45 // Keep only last 1000 visitors
46 $stats['visitors'] = array_slice($stats['visitors'], 0, 1000);
47
48 // Update page visits
49 if (!isset($stats['pages'][$page])) {
50 $stats['pages'][$page] = 0;
51 }
52 $stats['pages'][$page]++;
53
54 file_put_contents('stats.json', json_encode($stats, JSON_PRETTY_PRINT));
55}
56
57// Get IP geolocation
58function getGeolocation($ip) {
59 if ($ip === '127.0.0.1' || $ip === '::1') {
60 return ['country' => 'Local', 'city' => 'Local', 'region' => 'Local'];
61 }
62
63 $url = "http://ip-api.com/json/{$ip}";
64 $response = @file_get_contents($url);
65
66 if ($response) {
67 $data = json_decode($response, true);
68 if ($data['status'] === 'success') {
69 return [
70 'country' => $data['country'],
71 'city' => $data['city'],
72 'region' => $data['regionName']
73 ];
74 }
75 }
76
77 return ['country' => 'Unknown', 'city' => 'Unknown', 'region' => 'Unknown'];
78}
79
80// Initialize and log current visit
81initStats();
82logVisitor('Stats Page');
83$stats = json_decode(file_get_contents('stats.json'), true);
84?>
85
86<!DOCTYPE html>
87<html lang="en">
88<head>
89 <meta charset="UTF-8">
90 <meta name="viewport" content="width=device-width, initial-scale=1.0">
91 <title>Website Statistics</title>
92 <style>
93 :root {
94 --primary: #4361ee;
95 --secondary: #3a0ca3;
96 --success: #4cc9f0;
97 --danger: #f72585;
98 --warning: #f8961e;
99 --info: #4895ef;
100 --dark: #2b2d42;
101 --light: #f8f9fa;
102 --gray: #6c757d;
103 }
104
105 * {
106 margin: 0;
107 padding: 0;
108 box-sizing: border-box;
109 }
110
111 body {
112 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
113 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
114 min-height: 100vh;
115 padding: 20px;
116 }
117
118 .container {
119 max-width: 1400px;
120 margin: 0 auto;
121 }
122
123 .header {
124 background: rgba(255, 255, 255, 0.95);
125 backdrop-filter: blur(10px);
126 border-radius: 20px;
127 padding: 30px;
128 margin-bottom: 30px;
129 box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
130 border: 1px solid rgba(255, 255, 255, 0.2);
131 }
132
133 .header h1 {
134 color: var(--dark);
135 font-size: 2.5rem;
136 margin-bottom: 10px;
137 background: linear-gradient(135deg, var(--primary), var(--secondary));
138 -webkit-background-clip: text;
139 -webkit-text-fill-color: transparent;
140 }
141
142 .stats-grid {
143 display: grid;
144 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
145 gap: 20px;
146 margin-bottom: 30px;
147 }
148
149 .stat-card {
150 background: rgba(255, 255, 255, 0.95);
151 backdrop-filter: blur(10px);
152 border-radius: 15px;
153 padding: 25px;
154 text-align: center;
155 box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
156 border: 1px solid rgba(255, 255, 255, 0.2);
157 transition: transform 0.3s ease, box-shadow 0.3s ease;
158 }
159
160 .stat-card:hover {
161 transform: translateY(-5px);
162 box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
163 }
164
165 .stat-number {
166 font-size: 2.5rem;
167 font-weight: bold;
168 color: var(--primary);
169 margin-bottom: 10px;
170 }
171
172 .stat-label {
173 color: var(--gray);
174 font-size: 0.9rem;
175 text-transform: uppercase;
176 letter-spacing: 1px;
177 }
178
179 .dashboard {
180 display: grid;
181 grid-template-columns: 1fr 1fr;
182 gap: 30px;
183 margin-bottom: 30px;
184 }
185
186 @media (max-width: 1024px) {
187 .dashboard {
188 grid-template-columns: 1fr;
189 }
190 }
191
192 .panel {
193 background: rgba(255, 255, 255, 0.95);
194 backdrop-filter: blur(10px);
195 border-radius: 20px;
196 padding: 30px;
197 box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
198 border: 1px solid rgba(255, 255, 255, 0.2);
199 }
200
201 .panel h2 {
202 color: var(--dark);
203 margin-bottom: 20px;
204 font-size: 1.5rem;
205 border-bottom: 2px solid var(--primary);
206 padding-bottom: 10px;
207 }
208
209 .visitor-list, .pages-list {
210 max-height: 400px;
211 overflow-y: auto;
212 }
213
214 .visitor-item, .page-item {
215 display: flex;
216 justify-content: space-between;
217 align-items: center;
218 padding: 15px;
219 border-bottom: 1px solid rgba(0, 0, 0, 0.1);
220 transition: background-color 0.3s ease;
221 }
222
223 .visitor-item:hover, .page-item:hover {
224 background-color: rgba(67, 97, 238, 0.05);
225 border-radius: 10px;
226 }
227
228 .visitor-info {
229 display: flex;
230 flex-direction: column;
231 gap: 5px;
232 }
233
234 .visitor-ip {
235 font-weight: bold;
236 color: var(--dark);
237 }
238
239 .visitor-location {
240 font-size: 0.85rem;
241 color: var(--gray);
242 }
243
244 .visitor-time {
245 font-size: 0.8rem;
246 color: var(--gray);
247 }
248
249 .page-name {
250 flex-grow: 1;
251 }
252
253 .page-count {
254 background: var(--primary);
255 color: white;
256 padding: 5px 12px;
257 border-radius: 20px;
258 font-size: 0.8rem;
259 font-weight: bold;
260 }
261
262 .admin-link {
263 display: inline-block;
264 background: linear-gradient(135deg, var(--primary), var(--secondary));
265 color: white;
266 padding: 12px 30px;
267 border-radius: 25px;
268 text-decoration: none;
269 font-weight: bold;
270 transition: all 0.3s ease;
271 box-shadow: 0 5px 15px rgba(67, 97, 238, 0.3);
272 }
273
274 .admin-link:hover {
275 transform: translateY(-2px);
276 box-shadow: 0 8px 25px rgba(67, 97, 238, 0.4);
277 }
278
279 .flag {
280 font-size: 1.2rem;
281 margin-right: 8px;
282 }
283
284 /* Scrollbar styling */
285 ::-webkit-scrollbar {
286 width: 6px;
287 }
288
289 ::-webkit-scrollbar-track {
290 background: rgba(0, 0, 0, 0.1);
291 border-radius: 10px;
292 }
293
294 ::-webkit-scrollbar-thumb {
295 background: var(--primary);
296 border-radius: 10px;
297 }
298
299 ::-webkit-scrollbar-thumb:hover {
300 background: var(--secondary);
301 }
302 </style>
303</head>
304<body>
305 <div class="container">
306 <div class="header">
307 <h1>📊 Website Analytics</h1>
308 <p>Real-time statistics and visitor insights</p>
309 </div>
310
311 <?php
312 // Calculate statistics
313 $totalVisitors = count($stats['visitors']);
314 $today = date('Y-m-d');
315 $dailyVisitors = array_filter($stats['visitors'], function($visitor) use ($today) {
316 return strpos($visitor['timestamp'], $today) === 0;
317 });
318 $dailyCount = count($dailyVisitors);
319
320 // Get unique visitors (by IP)
321 $uniqueIPs = array_unique(array_column($stats['visitors'], 'ip'));
322 $uniqueVisitors = count($uniqueIPs);
323
324 // Get countries
325 $countries = array_count_values(array_column($stats['visitors'], 'country'));
326 $countryCount = count($countries);
327 ?>
328
329 <div class="stats-grid">
330 <div class="stat-card">
331 <div class="stat-number"><?php echo $totalVisitors; ?></div>
332 <div class="stat-label">Total Visitors</div>
333 </div>
334 <div class="stat-card">
335 <div class="stat-number"><?php echo $dailyCount; ?></div>
336 <div class="stat-label">Today's Visitors</div>
337 </div>
338 <div class="stat-card">
339 <div class="stat-number"><?php echo $uniqueVisitors; ?></div>
340 <div class="stat-label">Unique Visitors</div>
341 </div>
342 <div class="stat-card">
343 <div class="stat-number"><?php echo $countryCount; ?></div>
344 <div class="stat-label">Countries</div>
345 </div>
346 </div>
347
348 <div class="dashboard">
349 <div class="panel">
350 <h2>🌍 Last 100 Visitors</h2>
351 <div class="visitor-list">
352 <?php
353 $recentVisitors = array_slice($stats['visitors'], 0, 100);
354 foreach ($recentVisitors as $visitor):
355 ?>
356 <div class="visitor-item">
357 <div class="visitor-info">
358 <div class="visitor-ip">
359 <span class="flag">📍</span>
360 <?php echo htmlspecialchars($visitor['ip']); ?>
361 </div>
362 <div class="visitor-location">
363 <?php echo htmlspecialchars($visitor['city'] . ', ' . $visitor['country']); ?>
364 </div>
365 <div class="visitor-time">
366 <?php echo htmlspecialchars($visitor['timestamp']); ?>
367 </div>
368 </div>
369 </div>
370 <?php endforeach; ?>
371 </div>
372 </div>
373
374 <div class="panel">
375 <h2>📈 Top 25 Pages</h2>
376 <div class="pages-list">
377 <?php
378 if (!empty($stats['pages'])) {
379 arsort($stats['pages']);
380 $topPages = array_slice($stats['pages'], 0, 25, true);
381 foreach ($topPages as $page => $count):
382 ?>
383 <div class="page-item">
384 <div class="page-name"><?php echo htmlspecialchars($page); ?></div>
385 <div class="page-count"><?php echo $count; ?></div>
386 </div>
387 <?php
388 endforeach;
389 } else {
390 echo '<div class="page-item">No page visits recorded yet.</div>';
391 }
392 ?>
393 </div>
394 </div>
395 </div>
396
397 <div style="text-align: center; margin-top: 30px;">
398 <a href="admin.php" class="admin-link">🔒 Admin Panel</a>
399 </div>
400 </div>
401</body>
402</html>