mnpx commited on
Commit
5f969a1
·
verified ·
1 Parent(s): ff0fb65

Create templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +210 -0
templates/index.html ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Snowflake Proxy - Live Stats</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ color: white;
18
+ min-height: 100vh;
19
+ padding: 20px;
20
+ }
21
+
22
+ .container {
23
+ max-width: 1200px;
24
+ margin: 0 auto;
25
+ }
26
+
27
+ h1 {
28
+ text-align: center;
29
+ font-size: 3em;
30
+ margin-bottom: 10px;
31
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
32
+ }
33
+
34
+ .subtitle {
35
+ text-align: center;
36
+ opacity: 0.9;
37
+ margin-bottom: 40px;
38
+ }
39
+
40
+ .stats-grid {
41
+ display: grid;
42
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
43
+ gap: 20px;
44
+ margin-bottom: 30px;
45
+ }
46
+
47
+ .stat-card {
48
+ background: rgba(255, 255, 255, 0.1);
49
+ backdrop-filter: blur(10px);
50
+ border-radius: 15px;
51
+ padding: 30px;
52
+ text-align: center;
53
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
54
+ border: 1px solid rgba(255,255,255,0.2);
55
+ transition: transform 0.3s ease;
56
+ }
57
+
58
+ .stat-card:hover {
59
+ transform: translateY(-5px);
60
+ }
61
+
62
+ .stat-number {
63
+ font-size: 3em;
64
+ font-weight: bold;
65
+ margin: 10px 0;
66
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
67
+ }
68
+
69
+ .stat-label {
70
+ font-size: 1.1em;
71
+ opacity: 0.9;
72
+ text-transform: uppercase;
73
+ letter-spacing: 2px;
74
+ }
75
+
76
+ .logs-container {
77
+ background: rgba(0, 0, 0, 0.3);
78
+ backdrop-filter: blur(10px);
79
+ border-radius: 15px;
80
+ padding: 20px;
81
+ border: 1px solid rgba(255,255,255,0.2);
82
+ }
83
+
84
+ .logs-header {
85
+ font-size: 1.5em;
86
+ margin-bottom: 15px;
87
+ padding-bottom: 10px;
88
+ border-bottom: 2px solid rgba(255,255,255,0.3);
89
+ }
90
+
91
+ .logs {
92
+ height: 400px;
93
+ overflow-y: auto;
94
+ font-family: 'Courier New', monospace;
95
+ font-size: 0.9em;
96
+ line-height: 1.6;
97
+ }
98
+
99
+ .log-entry {
100
+ padding: 5px;
101
+ border-left: 3px solid #4ade80;
102
+ margin: 5px 0;
103
+ padding-left: 10px;
104
+ background: rgba(255,255,255,0.05);
105
+ border-radius: 3px;
106
+ }
107
+
108
+ .pulse {
109
+ animation: pulse 2s infinite;
110
+ }
111
+
112
+ @keyframes pulse {
113
+ 0%, 100% { opacity: 1; }
114
+ 50% { opacity: 0.7; }
115
+ }
116
+
117
+ .footer {
118
+ text-align: center;
119
+ margin-top: 40px;
120
+ opacity: 0.8;
121
+ font-size: 0.9em;
122
+ }
123
+
124
+ ::-webkit-scrollbar {
125
+ width: 10px;
126
+ }
127
+
128
+ ::-webkit-scrollbar-track {
129
+ background: rgba(255,255,255,0.1);
130
+ border-radius: 5px;
131
+ }
132
+
133
+ ::-webkit-scrollbar-thumb {
134
+ background: rgba(255,255,255,0.3);
135
+ border-radius: 5px;
136
+ }
137
+
138
+ ::-webkit-scrollbar-thumb:hover {
139
+ background: rgba(255,255,255,0.5);
140
+ }
141
+ </style>
142
+ </head>
143
+ <body>
144
+ <div class="container">
145
+ <h1>🌨️ Snowflake Proxy</h1>
146
+ <p class="subtitle">Helping people bypass censorship in real-time</p>
147
+
148
+ <div class="stats-grid">
149
+ <div class="stat-card">
150
+ <div class="stat-label">People Helped</div>
151
+ <div class="stat-number pulse" id="total-helped">0</div>
152
+ </div>
153
+
154
+ <div class="stat-card">
155
+ <div class="stat-label">Active Connections</div>
156
+ <div class="stat-number" id="current-connections">0</div>
157
+ </div>
158
+
159
+ <div class="stat-card">
160
+ <div class="stat-label">Uptime</div>
161
+ <div class="stat-number" id="uptime">0:00</div>
162
+ </div>
163
+ </div>
164
+
165
+ <div class="logs-container">
166
+ <div class="logs-header">📋 Live Logs</div>
167
+ <div class="logs" id="logs">
168
+ <div class="log-entry">Starting Snowflake proxy...</div>
169
+ </div>
170
+ </div>
171
+
172
+ <div class="footer">
173
+ <p>Running on Hugging Face Spaces 🤗 | Fighting Internet Censorship 🔓</p>
174
+ </div>
175
+ </div>
176
+
177
+ <script>
178
+ // Fetch stats every 2 seconds
179
+ function updateStats() {
180
+ fetch('/api/stats')
181
+ .then(response => response.json())
182
+ .then(data => {
183
+ document.getElementById('total-helped').textContent = data.total_helped;
184
+ document.getElementById('current-connections').textContent = data.current_connections;
185
+
186
+ // Calculate uptime
187
+ const start = new Date(data.start_time);
188
+ const now = new Date();
189
+ const diff = Math.floor((now - start) / 1000);
190
+ const hours = Math.floor(diff / 3600);
191
+ const minutes = Math.floor((diff % 3600) / 60);
192
+ document.getElementById('uptime').textContent = `${hours}:${minutes.toString().padStart(2, '0')}`;
193
+
194
+ // Update logs
195
+ const logsContainer = document.getElementById('logs');
196
+ logsContainer.innerHTML = data.logs.map(log =>
197
+ `<div class="log-entry">${log.message}</div>`
198
+ ).join('');
199
+
200
+ // Auto-scroll to bottom
201
+ logsContainer.scrollTop = logsContainer.scrollHeight;
202
+ });
203
+ }
204
+
205
+ // Update immediately and then every 2 seconds
206
+ updateStats();
207
+ setInterval(updateStats, 2000);
208
+ </script>
209
+ </body>
210
+ </html>