navpan2 commited on
Commit
b748560
·
verified ·
1 Parent(s): 5d16355

Create admin.html

Browse files
Files changed (1) hide show
  1. templates/admin.html +230 -0
templates/admin.html ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Admin Panel - Code Snippets</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
+ margin: 0;
11
+ padding: 20px;
12
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
13
+ min-height: 100vh;
14
+ color: white;
15
+ }
16
+ .container {
17
+ max-width: 1000px;
18
+ margin: 0 auto;
19
+ background: rgba(255, 255, 255, 0.1);
20
+ padding: 30px;
21
+ border-radius: 15px;
22
+ backdrop-filter: blur(10px);
23
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
24
+ }
25
+ h1 {
26
+ text-align: center;
27
+ margin-bottom: 30px;
28
+ font-size: 2.5em;
29
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
30
+ }
31
+ .snippet-grid {
32
+ display: grid;
33
+ grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
34
+ gap: 25px;
35
+ }
36
+ .snippet-card {
37
+ background: rgba(255, 255, 255, 0.15);
38
+ padding: 25px;
39
+ border-radius: 12px;
40
+ border: 2px solid rgba(255, 255, 255, 0.2);
41
+ }
42
+ .snippet-header {
43
+ display: flex;
44
+ justify-content: space-between;
45
+ align-items: center;
46
+ margin-bottom: 15px;
47
+ }
48
+ .endpoint-name {
49
+ font-size: 1.3em;
50
+ font-weight: bold;
51
+ color: #fff;
52
+ background: rgba(255, 255, 255, 0.2);
53
+ padding: 8px 15px;
54
+ border-radius: 20px;
55
+ }
56
+ .test-link {
57
+ color: #fff;
58
+ text-decoration: none;
59
+ background: rgba(0, 255, 0, 0.3);
60
+ padding: 5px 12px;
61
+ border-radius: 15px;
62
+ font-size: 0.9em;
63
+ transition: background 0.3s ease;
64
+ }
65
+ .test-link:hover {
66
+ background: rgba(0, 255, 0, 0.5);
67
+ }
68
+ textarea {
69
+ width: 100%;
70
+ height: 150px;
71
+ background: rgba(0, 0, 0, 0.3);
72
+ border: 2px solid rgba(255, 255, 255, 0.3);
73
+ border-radius: 8px;
74
+ padding: 15px;
75
+ color: white;
76
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
77
+ font-size: 14px;
78
+ resize: vertical;
79
+ box-sizing: border-box;
80
+ line-height: 1.4;
81
+ tab-size: 4;
82
+ white-space: pre;
83
+ overflow-wrap: break-word;
84
+ }
85
+ textarea:focus {
86
+ outline: none;
87
+ border-color: rgba(255, 255, 255, 0.6);
88
+ background: rgba(0, 0, 0, 0.4);
89
+ }
90
+ .update-btn {
91
+ background: linear-gradient(45deg, #28a745, #20c997);
92
+ color: white;
93
+ border: none;
94
+ padding: 12px 25px;
95
+ border-radius: 25px;
96
+ cursor: pointer;
97
+ font-weight: bold;
98
+ transition: all 0.3s ease;
99
+ margin-top: 15px;
100
+ width: 100%;
101
+ }
102
+ .update-btn:hover {
103
+ transform: translateY(-2px);
104
+ box-shadow: 0 5px 15px rgba(40, 167, 69, 0.4);
105
+ }
106
+ .back-btn {
107
+ display: inline-block;
108
+ background: rgba(255, 255, 255, 0.2);
109
+ color: white;
110
+ padding: 12px 25px;
111
+ border: 2px solid rgba(255, 255, 255, 0.3);
112
+ border-radius: 25px;
113
+ text-decoration: none;
114
+ font-weight: bold;
115
+ transition: all 0.3s ease;
116
+ margin-bottom: 30px;
117
+ }
118
+ .back-btn:hover {
119
+ background: rgba(255, 255, 255, 0.3);
120
+ border-color: rgba(255, 255, 255, 0.5);
121
+ }
122
+ .success-message {
123
+ background: rgba(40, 167, 69, 0.3);
124
+ border: 2px solid rgba(40, 167, 69, 0.5);
125
+ color: white;
126
+ padding: 15px;
127
+ border-radius: 8px;
128
+ margin-bottom: 20px;
129
+ text-align: center;
130
+ }
131
+ </style>
132
+ </head>
133
+ <body>
134
+ <div class="container">
135
+ <a href="/" class="back-btn">← Back to Home</a>
136
+
137
+ <h1>🛠️ Admin Panel</h1>
138
+
139
+ <div class="snippet-grid">
140
+ {% for snippet in snippets %}
141
+ <div class="snippet-card">
142
+ <div class="snippet-header">
143
+ <span class="endpoint-name">/{{ snippet.endpoint }}</span>
144
+ <a href="/{{ snippet.endpoint }}" target="_blank" class="test-link">Test</a>
145
+ </div>
146
+
147
+ <form method="POST" action="/update_snippet">
148
+ <input type="hidden" name="endpoint" value="{{ snippet.endpoint }}">
149
+ <textarea name="text" placeholder="Enter your code snippet here...">{{ snippet.text }}</textarea>
150
+ <button type="submit" class="update-btn">Update {{ snippet.endpoint }}</button>
151
+ </form>
152
+ </div>
153
+ {% endfor %}
154
+ </div>
155
+ </div>
156
+
157
+ <script>
158
+ // Auto-resize textareas and handle Tab key for proper indentation
159
+ document.querySelectorAll('textarea').forEach(textarea => {
160
+ // Auto-resize functionality
161
+ textarea.addEventListener('input', function() {
162
+ this.style.height = 'auto';
163
+ this.style.height = Math.max(150, this.scrollHeight) + 'px';
164
+ });
165
+
166
+ // Handle Tab key for indentation
167
+ textarea.addEventListener('keydown', function(e) {
168
+ if (e.key === 'Tab') {
169
+ e.preventDefault();
170
+
171
+ const start = this.selectionStart;
172
+ const end = this.selectionEnd;
173
+ const value = this.value;
174
+
175
+ if (e.shiftKey) {
176
+ // Shift+Tab: Remove indentation
177
+ const lineStart = value.lastIndexOf('\n', start - 1) + 1;
178
+ const lineText = value.substring(lineStart, value.indexOf('\n', lineStart));
179
+
180
+ if (lineText.startsWith(' ')) {
181
+ this.value = value.substring(0, lineStart) +
182
+ lineText.substring(4) +
183
+ value.substring(lineStart + lineText.length);
184
+ this.selectionStart = this.selectionEnd = start - 4;
185
+ }
186
+ } else {
187
+ // Tab: Add indentation (4 spaces)
188
+ this.value = value.substring(0, start) + ' ' + value.substring(end);
189
+ this.selectionStart = this.selectionEnd = start + 4;
190
+ }
191
+ }
192
+
193
+ // Auto-indent on Enter with language-aware indentation
194
+ if (e.key === 'Enter') {
195
+ const start = this.selectionStart;
196
+ const value = this.value;
197
+ const lineStart = value.lastIndexOf('\n', start - 1) + 1;
198
+ const currentLine = value.substring(lineStart, start);
199
+ const indent = currentLine.match(/^(\s*)/)[1];
200
+
201
+ // Language-aware auto-indentation
202
+ let extraIndent = '';
203
+ const trimmedLine = currentLine.trim();
204
+
205
+ // Add extra indent for various language constructs
206
+ if (trimmedLine.endsWith(':') || // Python
207
+ trimmedLine.endsWith('{') || // C++, Java, JavaScript
208
+ trimmedLine.includes('if') && trimmedLine.endsWith(')') || // C++ if without {
209
+ trimmedLine.includes('for') && trimmedLine.endsWith(')') || // C++ for without {
210
+ trimmedLine.includes('while') && trimmedLine.endsWith(')') // C++ while without {
211
+ ) {
212
+ extraIndent = ' ';
213
+ }
214
+
215
+ setTimeout(() => {
216
+ const newStart = this.selectionStart;
217
+ this.value = this.value.substring(0, newStart) +
218
+ indent + extraIndent +
219
+ this.value.substring(newStart);
220
+ this.selectionStart = this.selectionEnd = newStart + indent.length + extraIndent.length;
221
+ }, 0);
222
+ }
223
+ });
224
+
225
+ // Set initial height
226
+ textarea.style.height = Math.max(150, textarea.scrollHeight) + 'px';
227
+ });
228
+ </script>
229
+ </body>
230
+ </html>