amauricunha commited on
Commit
3c0a9b5
·
verified ·
1 Parent(s): 2b943d1

Upload 4 files

Browse files
templates/admin.html CHANGED
@@ -54,233 +54,16 @@
54
  </button>
55
  <button onclick="showTab('users')" class="admin-tab" data-tab="users">
56
  👥 Users
57
- </button>
58
- <button onclick="showTab('database')" class="admin-tab" data-tab="database">
59
- 🗄️ Database
60
- </button>
61
- <button onclick="showTab('tokens')" class="admin-tab" data-tab="tokens">
62
- 🎯 Token Usage
63
- </button>
64
- <button onclick="showTab('system')" class="admin-tab" data-tab="system">
65
- 🖥️ System Health
66
- </button>
67
- </nav>
68
- </div>
69
- </div>
70
-
71
- <!-- Tab Content -->
72
- <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
73
- <!-- Dashboard Tab -->
74
- <div id="dashboardTab" class="tab-content">
75
- <h2 class="text-2xl font-bold mb-6">📊 System Dashboard</h2>
76
-
77
- <!-- System Stats Cards -->
78
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
79
- <div class="stat-card">
80
- <h3 class="text-lg font-semibold mb-2">👥 Total Users</h3>
81
- <p id="totalUsers" class="text-3xl font-bold">-</p>
82
- <p class="text-sm opacity-80">
83
- <span id="newUsersWeek">-</span> this week
84
- </p>
85
- </div>
86
- <div class="stat-card">
87
- <h3 class="text-lg font-semibold mb-2">📚 Study Sessions</h3>
88
- <p id="totalSessions" class="text-3xl font-bold">-</p>
89
- <p class="text-sm opacity-80">All time</p>
90
- </div>
91
- <div class="stat-card">
92
- <h3 class="text-lg font-semibold mb-2">🎯 API Tokens</h3>
93
- <p id="totalTokens" class="text-3xl font-bold">-</p>
94
- <p class="text-sm opacity-80">
95
- $<span id="estimatedCost">-</span> estimated cost
96
- </p>
97
- </div>
98
- <div class="stat-card">
99
- <h3 class="text-lg font-semibold mb-2">📝 Content Items</h3>
100
- <p id="totalContent" class="text-3xl font-bold">-</p>
101
- <p class="text-sm opacity-80">Articles & flashcards</p>
102
- </div>
103
- </div>
104
-
105
- <!-- Charts Section -->
106
- <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
107
- <div class="admin-card">
108
- <h3 class="text-lg font-semibold mb-4">📈 User Growth</h3>
109
- <canvas id="userGrowthChart" width="400" height="200"></canvas>
110
- </div>
111
- <div class="admin-card">
112
- <h3 class="text-lg font-semibold mb-4">💰 Token Usage Costs</h3>
113
- <canvas id="tokenCostChart" width="400" height="200"></canvas>
114
- </div>
115
- </div>
116
-
117
- <!-- Recent Activity -->
118
- <div class="admin-card">
119
- <h3 class="text-lg font-semibold mb-4">🔄 Recent Activity</h3>
120
- <div id="recentActivity" class="space-y-2">
121
- <div class="text-center text-gray-500 py-4">Loading recent activity...</div>
122
- </div>
123
- </div>
124
- </div>
125
-
126
- <!-- Users Tab -->
127
- <!-- Users Tab removed: user management is not available in open version -->
128
-
129
- <!-- Database Tab -->
130
- <div id="databaseTab" class="tab-content hidden">
131
- <h2 class="text-2xl font-bold mb-6">🗄️ Database Overview</h2>
132
-
133
- <div class="admin-card">
134
- <h3 class="text-lg font-semibold mb-4">📋 Database Schema</h3>
135
- <div id="databaseSchema" class="space-y-4">
136
- <div class="text-center text-gray-500 py-4">Loading schema...</div>
137
- </div>
138
- </div>
139
- </div>
140
-
141
- <!-- Token Usage Tab -->
142
- <div id="tokensTab" class="tab-content hidden">
143
- <div class="flex justify-between items-center mb-6">
144
- <h2 class="text-2xl font-bold">🎯 Token Usage Analytics</h2>
145
- <button onclick="exportTokens()" class="bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600">
146
- 📥 Export Token Data
147
- </button>
148
- </div>
149
-
150
- <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
151
- <div class="admin-card">
152
- <h3 class="text-lg font-semibold mb-4">📊 Usage by Provider</h3>
153
- <canvas id="providerUsageChart" width="400" height="300"></canvas>
154
- </div>
155
- <div class="admin-card">
156
- <h3 class="text-lg font-semibold mb-4">💰 Cost Breakdown</h3>
157
- <canvas id="costBreakdownChart" width="400" height="300"></canvas>
158
- </div>
159
- </div>
160
- </div>
161
-
162
- <!-- System Health Tab -->
163
- <div id="systemTab" class="tab-content hidden">
164
- <h2 class="text-2xl font-bold mb-6">🖥️ System Health Monitor</h2>
165
-
166
- <!-- System Alerts -->
167
- <div class="admin-card mb-6">
168
- <h3 class="text-lg font-semibold mb-4">⚠️ System Alerts</h3>
169
- <div id="systemAlerts">
170
- <div class="text-center text-gray-500 py-4">Loading alerts...</div>
171
- </div>
172
- </div>
173
-
174
- <!-- System Metrics -->
175
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6">
176
- <div class="admin-card">
177
- <h4 class="font-semibold mb-3">💾 Memory Usage</h4>
178
- <div id="memoryMetrics">
179
- <div class="text-sm text-gray-500">Loading...</div>
180
- </div>
181
- </div>
182
-
183
- <div class="admin-card">
184
- <h4 class="font-semibold mb-3">💿 Disk Usage</h4>
185
- <div id="diskMetrics">
186
- <div class="text-sm text-gray-500">Loading...</div>
187
- </div>
188
- </div>
189
-
190
- <div class="admin-card">
191
- <h4 class="font-semibold mb-3">🗄️ Database</h4>
192
- <div id="databaseMetrics">
193
- <div class="text-sm text-gray-500">Loading...</div>
194
- </div>
195
- </div>
196
- </div>
197
-
198
- <!-- Error Logs -->
199
- <div class="admin-card">
200
- <h3 class="text-lg font-semibold mb-4">🚨 Recent Errors</h3>
201
- <div id="errorLogs">
202
- <div class="text-center text-gray-500 py-4">Loading error logs...</div>
203
- </div>
204
- </div>
205
- </div>
206
- </div>
207
- </div>
208
-
209
- <!-- User Detail Modal removed -->
210
-
211
- <!-- Toast Notifications -->
212
- <div id="toastContainer" class="fixed top-4 right-4 z-50"></div>
213
-
214
- <script>
215
- // User logic, authentication, and user management removed. Admin panel is always accessible.
216
-
217
- // Tab management (users tab removed)
218
- function showTab(tabName) {
219
- document.querySelectorAll('.tab-content').forEach(tab => {
220
- tab.classList.add('hidden');
221
- });
222
- document.querySelectorAll('.admin-tab').forEach(btn => {
223
- btn.classList.remove('active', 'border-blue-500', 'text-blue-600');
224
- btn.classList.add('border-transparent', 'text-gray-500');
225
- });
226
- document.getElementById(tabName + 'Tab').classList.remove('hidden');
227
- const activeBtn = document.querySelector(`[data-tab="${tabName}"]`);
228
- activeBtn.classList.add('active', 'border-blue-500', 'text-blue-600');
229
- activeBtn.classList.remove('border-transparent', 'text-gray-500');
230
- if (tabName === 'dashboard') {
231
- loadDashboard();
232
- } else if (tabName === 'database') {
233
- loadDatabaseSchema();
234
- } else if (tabName === 'tokens') {
235
- loadTokenUsage();
236
- } else if (tabName === 'system') {
237
- loadSystemHealth();
238
- }
239
- }
240
-
241
- async function loadDashboard() {
242
- try {
243
- const response = await fetch('/admin/dashboard');
244
- const data = await response.json();
245
-
246
- if (data.success) {
247
- const stats = data.stats;
248
-
249
- // Update stat cards
250
- document.getElementById('totalUsers').textContent = stats.users?.total || 0;
251
- document.getElementById('newUsersWeek').textContent = stats.users?.new_week || 0;
252
- document.getElementById('totalSessions').textContent = stats.activity?.total_sessions || 0;
253
- document.getElementById('totalTokens').textContent = (stats.api_usage?.total_tokens || 0).toLocaleString();
254
- document.getElementById('estimatedCost').textContent = stats.api_usage?.estimated_cost || '0.00';
255
- document.getElementById('totalContent').textContent =
256
- (stats.activity?.total_flashcards || 0) + (stats.activity?.total_articles || 0);
257
-
258
- // Update recent activity
259
- updateRecentActivity(stats.recent_activity || []);
260
-
261
- // Create charts
262
- createCharts(stats);
263
- }
264
- } catch (error) {
265
- console.error('Dashboard loading error:', error);
266
- showToast('Failed to load dashboard', 'error');
267
- }
268
- }
269
-
270
- function updateRecentActivity(activities) {
271
- const container = document.getElementById('recentActivity');
272
-
273
- if (activities.length === 0) {
274
- container.innerHTML = '<div class="text-center text-gray-500 py-4">No recent activity</div>';
275
- return;
276
- }
277
-
278
- container.innerHTML = activities.map(activity => `
279
- <div class="flex items-center justify-between py-2 border-b border-gray-100">
280
- <div>
281
- <span class="font-medium">${activity.user}</span>
282
- <span class="text-gray-600">performed ${activity.activity}</span>
283
  </div>
 
284
  <span class="text-sm text-gray-500">${formatDate(activity.timestamp)}</span>
285
  </div>
286
  `).join('');
 
54
  </button>
55
  <button onclick="showTab('users')" class="admin-tab" data-tab="users">
56
  👥 Users
57
+ {% extends "base.html" %}
58
+ {% block title %}Admin - English Helper{% endblock %}
59
+ {% block content %}
60
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
61
+ <h1 class="text-2xl font-bold mb-4">Painel de Administração</h1>
62
+ <!-- Aqui vai o conteúdo do painel admin, tabs, cards, gráficos, etc. -->
63
+ <p>Gerencie usuários, flashcards e estatísticas do sistema.</p>
64
+ <!-- Mantenha seus scripts JS e componentes aqui, se necessário -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  </div>
66
+ {% endblock %}
67
  <span class="text-sm text-gray-500">${formatDate(activity.timestamp)}</span>
68
  </div>
69
  `).join('');
templates/base.html CHANGED
@@ -4,31 +4,15 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>English Helper - Admin Panel</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
- <style>
10
- /* Tailwind utility classes should be used directly in HTML, not via @apply in <style> */
11
- .spinner {
12
- border: 3px solid #f3f3f3;
13
- border-top: 3px solid #3498db;
14
- border-radius: 50%;
15
- width: 20px;
16
- height: 20px;
17
- animation: spin 1s linear infinite;
18
- display: inline-block;
19
- margin-right: 10px;
20
- }
21
- @keyframes spin {
22
- 0% { transform: rotate(0deg); }
23
- 100% { transform: rotate(360deg); }
24
- }
25
- .table-container {
26
- max-height: 600px;
27
- overflow-y: auto;
28
- }
29
- </style>
30
- </head>
31
- <body class="bg-gray-100 min-h-screen">
32
  <!-- Admin Login Modal removed: admin panel is always accessible -->
33
 
34
  <!-- Admin Interface -->
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>English Helper - Admin Panel</title>
7
+ <meta charset="UTF-8">
8
+ <title>{% block title %}English Helper{% endblock %}</title>
9
+ <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
10
+ <style>
11
+ nav { background: #f5f5f5; padding: 1em; margin-bottom: 2em; }
12
+ nav a { margin-right: 1em; text-decoration: none; color: #333; font-weight: bold; }
13
+ nav a:hover { color: #007bff; }
14
+ main { max-width: 900px; margin: auto; }
15
+ </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  <!-- Admin Login Modal removed: admin panel is always accessible -->
17
 
18
  <!-- Admin Interface -->
templates/index.html CHANGED
@@ -8,202 +8,16 @@
8
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
9
  <style>
10
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
11
- body { font-family: 'Inter', sans-serif; background-color: #f7f9fc; }
12
- .card { background-color: white; border-radius: 12px; box-shadow: 0 4px_12px rgba(0,0,0,0.08); padding: 24px; }
13
- .btn { padding: 0.5rem 1rem; border-radius: 8px; font-weight: 600; transition: all 0.2s; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
14
- .btn:disabled { cursor: not-allowed; opacity: 0.5; }
15
- .btn-primary { background-color: #4f46e5; color: white; }
16
- .btn-primary:hover:not(:disabled) { background-color: #4338ca; }
17
- .spinner { border: 2px solid rgba(255,255,255,0.3); width: 20px; height: 20px; border-radius: 50%; border-left-color: #fff; animation: spin 1s ease infinite; }
18
- @keyframes spin { to { transform: rotate(360deg); } }
19
- .flashcard-container { perspective: 1000px; position: relative; }
20
- .flashcard-inner { position: relative; width: 100%; transition: transform 0.6s; transform-style: preserve-3d; }
21
- .flashcard-container.flipped .flashcard-inner { transform: rotateY(180deg); }
22
- .flashcard-front, .flashcard-back { position: absolute; width: 100%; height:100%; backface-visibility: hidden; border: 1px solid #e5e7eb; border-radius: 12px; padding: 20px; display: flex; flex-direction: column; justify-content: space-between; }
23
- .flashcard-front { background-color: #f9fafb; }
24
- .flashcard-back { background-color: #ffffff; transform: rotateY(180deg); }
25
- .audio-btn { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: #4f46e5; padding: 0; }
26
- .delete-btn { position: absolute; top: 10px; right: 10px; background: none; border: none; font-size: 1.2rem; cursor: pointer; color: #9ca3af; z-index: 10; }
27
- .delete-btn:hover { color: #ef4444; }
28
- #activityChatDisplay { border: 1px solid #e5e7eb; border-radius: 8px; padding: 1rem; min-height: 150px; background-color: #f9fafb; }
29
- .ai-prompt { border-bottom: 2px dashed #d1d5db; padding-bottom: 1rem; margin-bottom: 1rem; }
30
- .user-response-display { background-color: #eef2ff; border-left: 4px solid #4f46e5; padding: 0.75rem; margin-bottom: 1rem; font-style: italic; }
31
- .ai-feedback { background-color: #f0fdf4; border-left: 4px solid #22c55e; padding: 0.75rem; }
32
- .ai-feedback h3 { font-weight: 700; }
33
-
34
- /* Toast Notifications */
35
- .toast-container { position: fixed; top: 20px; right: 20px; z-index: 1000; max-width: 400px; }
36
- .toast { background: white; border-left: 4px solid #4f46e5; border-radius: 8px; box-shadow: 0 10px 25px rgba(0,0,0,0.15); padding: 1rem; margin-bottom: 0.5rem; opacity: 0; transform: translateX(100%); transition: all 0.3s ease; }
37
- .toast.show { opacity: 1; transform: translateX(0); }
38
- .toast.error { border-left-color: #ef4444; }
39
- .toast.success { border-left-color: #10b981; }
40
- .toast.warning { border-left-color: #f59e0b; }
41
- .toast-close { float: right; background: none; border: none; font-size: 1.2rem; cursor: pointer; color: #9ca3af; }
42
-
43
- /* Loading States & Skeleton */
44
- .loading-skeleton {
45
- background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
46
- background-size: 200% 100%;
47
- animation: loading 1.5s infinite;
48
- border-radius: 4px;
49
- }
50
- @keyframes loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
51
-
52
- .skeleton-text { height: 1rem; margin: 0.25rem 0; }
53
- .skeleton-text.large { height: 1.5rem; }
54
- .skeleton-text.small { height: 0.75rem; }
55
- .skeleton-box { height: 100px; border-radius: 8px; }
56
-
57
- /* Enhanced Loading Spinner */
58
- .spinner-container { display: flex; align-items: center; justify-content: center; padding: 2rem; }
59
- .spinner-large { width: 40px; height: 40px; border-width: 4px; }
60
-
61
- /* Fade in animations */
62
- .fade-in { animation: fadeIn 0.5s ease-in; }
63
- @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
64
-
65
- /* Slide in animations */
66
- .slide-in { animation: slideIn 0.3s ease-out; }
67
- @keyframes slideIn { from { transform: translateX(-20px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
68
-
69
- /* Empty states */
70
- .empty-state {
71
- text-align: center; padding: 3rem 1rem; color: #6b7280;
72
- background: #f9fafb; border: 2px dashed #d1d5db; border-radius: 12px; margin: 1rem 0;
73
- }
74
- .empty-state-icon { font-size: 3rem; margin-bottom: 1rem; opacity: 0.5; }
75
- .empty-state-title { font-size: 1.25rem; font-weight: 600; margin-bottom: 0.5rem; color: #374151; }
76
- .empty-state-description { font-size: 0.875rem; line-height: 1.5; }
77
-
78
- /* Enhanced Flashcards - Responsive */
79
- .flashcard-container { perspective: 1000px; position: relative; }
80
- .flashcard-inner { position: relative; width: 100%; min-height: 280px; transition: transform 0.6s; transform-style: preserve-3d; }
81
- .flashcard-container.flipped .flashcard-inner { transform: rotateY(180deg); }
82
- .flashcard-front, .flashcard-back {
83
- position: absolute; width: 100%; height: 100%; min-height: 280px; backface-visibility: hidden;
84
- border: 1px solid #e5e7eb; border-radius: 12px; padding: 20px; display: flex; flex-direction: column;
85
- justify-content: space-between; word-wrap: break-word; overflow-wrap: break-word;
86
- }
87
- .flashcard-front { background-color: #f9fafb; }
88
- .flashcard-back { background-color: #ffffff; transform: rotateY(180deg); }
89
-
90
- /* Responsive text handling */
91
- .flashcard-text {
92
- font-size: 1rem; line-height: 1.5; max-height: 150px; overflow-y: auto;
93
- word-break: break-word; hyphens: auto; padding: 0.25rem 0;
94
- }
95
-
96
- /* Mobile responsiveness */
97
- @media (max-width: 768px) {
98
- .flashcard-text { font-size: 0.9rem; max-height: 120px; line-height: 1.4; }
99
- .flashcard-container { margin-bottom: 1rem; }
100
- .flashcard-inner { min-height: 250px; }
101
- .flashcard-front, .flashcard-back { min-height: 250px; padding: 16px; }
102
- .card { padding: 16px; }
103
- body { padding: 0.5rem; }
104
- .container { padding: 0; }
105
-
106
- /* Adjust grid for mobile */
107
- .grid.grid-cols-1.md\\:grid-cols-3 { grid-template-columns: 1fr; }
108
- .grid.grid-cols-1.lg\\:grid-cols-2 { grid-template-columns: 1fr; }
109
- }
110
-
111
- @media (max-width: 480px) {
112
- .flashcard-text { font-size: 0.85rem; max-height: 100px; }
113
- .flashcard-inner { min-height: 220px; }
114
- .flashcard-front, .flashcard-back { min-height: 220px; padding: 12px; }
115
-
116
- /* Make buttons more touch-friendly */
117
- .btn { padding: 0.75rem 1rem; min-height: 44px; }
118
- .audio-btn { font-size: 1.25rem; padding: 0.5rem; }
119
- .delete-btn { font-size: 1rem; padding: 0.5rem; }
120
- }
121
-
122
- /* Text overflow handling */
123
- .text-truncate {
124
- overflow: hidden;
125
- text-overflow: ellipsis;
126
- white-space: nowrap;
127
- }
128
-
129
- .text-wrap {
130
- white-space: normal;
131
- word-wrap: break-word;
132
- overflow-wrap: break-word;
133
- }
134
-
135
- /* Form Validation */
136
- .form-error { border-color: #ef4444 !important; }
137
- .error-message { color: #ef4444; font-size: 0.875rem; margin-top: 0.25rem; }
138
-
139
- /* Enhanced buttons */
140
- .btn { position: relative; overflow: hidden; }
141
- .btn::after { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; background: rgba(255,255,255,0.3); transform: translate(-50%, -50%); transition: width 0.3s, height 0.3s; }
142
- .btn:active::after { width: 300px; height: 300px; }
143
-
144
- /* Pulse animation for mic button */
145
- .mic-button.is-recording { animation: pulse 1.5s infinite; }
146
- @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }
147
-
148
- /* Auth Modal */
149
- .modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); }
150
- .modal.show { display: block; }
151
- .modal-content {
152
- background-color: white; margin: 5% auto; padding: 0; width: 90%; max-width: 400px;
153
- border-radius: 12px; position: relative; animation: modalSlideIn 0.3s ease;
154
- }
155
- @keyframes modalSlideIn { from { opacity: 0; transform: translateY(-50px); } to { opacity: 1; transform: translateY(0); } }
156
- .modal-header { padding: 1.5rem; border-bottom: 1px solid #e5e7eb; }
157
- .modal-body { padding: 1.5rem; }
158
- .modal-footer { padding: 1rem 1.5rem; border-top: 1px solid #e5e7eb; display: flex; justify-content: flex-end; gap: 0.5rem; }
159
- .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; cursor: pointer; }
160
- .close:hover { color: #000; }
161
-
162
- /* Auth Form */
163
- .auth-form { display: none; }
164
- .auth-form.active { display: block; }
165
- .form-group { margin-bottom: 1rem; }
166
- .form-group label { display: block; margin-bottom: 0.25rem; font-weight: 500; color: #374151; }
167
- .form-group input { width: 100%; padding: 0.75rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: 0.875rem; }
168
- .form-group input:focus { outline: none; border-color: #4f46e5; box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); }
169
-
170
- /* User Menu */
171
- .user-menu { position: relative; display: inline-block; }
172
- .user-menu-content { display: none; position: absolute; right: 0; background-color: white; min-width: 200px; box-shadow: 0 8px 16px rgba(0,0,0,0.1); border-radius: 8px; z-index: 1; border: 1px solid #e5e7eb; }
173
- .user-menu.show .user-menu-content { display: block; }
174
- .user-menu-item { padding: 0.75rem 1rem; display: block; color: #374151; text-decoration: none; border-bottom: 1px solid #f3f4f6; }
175
- .user-menu-item:hover { background-color: #f9fafb; }
176
- .user-menu-item:last-child { border-bottom: none; }
177
-
178
- /* Header Auth Section */
179
- .auth-section { display: flex; align-items: center; gap: 0.5rem; }
180
- .user-avatar { width: 40px; height: 40px; border-radius: 50%; background-color: #4f46e5; color: white; display: flex; align-items: center; justify-content: center; font-weight: 600; cursor: pointer; }
181
-
182
- /* Content Curation Styles */
183
- .content-item {
184
- border: 1px solid #e5e7eb; border-radius: 8px; padding: 1rem; margin-bottom: 1rem;
185
- background: white; transition: all 0.2s;
186
- }
187
- .content-item:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); border-color: #4f46e5; }
188
- .content-item-title { font-weight: 600; color: #1f2937; margin-bottom: 0.5rem; }
189
- .content-item-meta { font-size: 0.75rem; color: #6b7280; margin-bottom: 0.5rem; }
190
- .content-item-summary { font-size: 0.875rem; color: #4b5563; line-height: 1.5; }
191
- .difficulty-badge {
192
- display: inline-block; padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 500;
193
- }
194
- .difficulty-easy { background-color: #dcfce7; color: #166534; }
195
- .difficulty-medium { background-color: #fef3c7; color: #92400e; }
196
- .difficulty-hard { background-color: #fee2e2; color: #991b1b; }
197
-
198
- /* Analytics Styles */
199
- .metric-card {
200
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
201
- color: white; border-radius: 12px; padding: 1.5rem; text-align: center;
202
- }
203
- .metric-value { font-size: 2rem; font-weight: bold; margin-bottom: 0.5rem; }
204
- .metric-label { font-size: 0.875rem; opacity: 0.9; }
205
-
206
- /* Study Plan Styles */
207
  .plan-activity {
208
  display: flex; align-items: center; padding: 0.75rem; border-radius: 6px;
209
  border-left: 4px solid #4f46e5; background-color: #f8fafc; margin-bottom: 0.5rem;
 
8
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
9
  <style>
10
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
11
+ {% extends "base.html" %}
12
+ {% block title %}Início - English Helper{% endblock %}
13
+ {% block content %}
14
+ <div class="container mx-auto max-w-5xl">
15
+ <!-- Conteúdo principal da página inicial aqui -->
16
+ <h1 class="text-2xl font-bold mb-4">Bem-vindo ao English Helper!</h1>
17
+ <p>Use o menu acima para navegar entre as funções do sistema.</p>
18
+ <!-- Você pode inserir aqui os blocos e componentes do seu app -->
19
+ </div>
20
+ {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  .plan-activity {
22
  display: flex; align-items: center; padding: 0.75rem; border-radius: 6px;
23
  border-left: 4px solid #4f46e5; background-color: #f8fafc; margin-bottom: 0.5rem;
templates/status.html ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+ {% block title %}Status - English Helper{% endblock %}
3
+ {% block content %}
4
+ <h1>Status do Sistema</h1>
5
+ <p>Veja informações sobre o funcionamento e APIs do sistema.</p>
6
+ {% endblock %}