AliDu14 commited on
Commit
cf54b36
·
verified ·
1 Parent(s): 512e8e4

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +296 -129
index.html CHANGED
@@ -3,36 +3,47 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Учет рабочего времени</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
- .progress-bar {
11
- height: 8px;
12
- border-radius: 4px;
13
- background-color: #e5e7eb;
14
- overflow: hidden;
15
  }
16
 
17
- .progress-fill {
18
- height: 100%;
19
- border-radius: 4px;
20
- background-color: #3b82f6;
21
- transition: width 0.3s ease;
22
  }
23
 
24
- .floating-btn {
25
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
26
- transition: all 0.3s ease;
27
  }
28
 
29
- .floating-btn:hover {
30
- transform: translateY(-2px);
31
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
- .floating-btn:active {
35
- transform: translateY(0);
 
 
 
36
  }
37
 
38
  .pulse {
@@ -41,135 +52,202 @@
41
 
42
  @keyframes pulse {
43
  0% {
44
- box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);
45
  }
46
  70% {
47
- box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
48
  }
49
  100% {
50
- box-shadow: 0 0 0 0 rgba(59, 130, 246, 0);
51
  }
52
  }
53
 
54
  .fade-in {
55
- animation: fadeIn 0.5s ease-in;
56
  }
57
 
58
  @keyframes fadeIn {
59
  from { opacity: 0; transform: translateY(10px); }
60
  to { opacity: 1; transform: translateY(0); }
61
  }
 
 
 
 
 
 
 
 
 
 
62
  </style>
63
  </head>
64
- <body class="bg-gray-50 min-h-screen">
65
- <div class="container mx-auto px-4 py-8 max-w-3xl">
66
- <header class="text-center mb-8">
67
- <h1 class="text-3xl font-bold text-gray-800 mb-2">Учет рабочего времени</h1>
68
- <p class="text-gray-600">Отслеживайте свои рабочие часы и дни</p>
69
- </header>
70
-
71
- <div class="bg-white rounded-xl shadow-md p-6 mb-8">
72
- <div class="flex justify-between items-center mb-6">
73
- <div>
74
- <h2 class="text-xl font-semibold text-gray-800">Текущий статус</h2>
75
- <p class="text-gray-500 text-sm" id="current-date">Сегодня: </p>
 
 
 
 
 
 
 
 
76
  </div>
77
- <div class="bg-blue-50 text-blue-800 px-4 py-2 rounded-lg">
78
- <span class="font-medium" id="current-status">Не начат</span>
 
 
 
 
 
 
79
  </div>
80
- </div>
81
-
82
- <div class="grid grid-cols-2 gap-4 mb-6">
83
- <button id="start-btn" class="floating-btn pulse bg-green-500 hover:bg-green-600 text-white py-4 px-6 rounded-lg font-medium flex items-center justify-center">
84
- <i class="fas fa-play mr-2"></i> Начало дня
85
- </button>
86
- <button id="end-btn" class="floating-btn bg-red-500 hover:bg-red-600 text-white py-4 px-6 rounded-lg font-medium flex items-center justify-center" disabled>
87
- <i class="fas fa-stop mr-2"></i> Конец дня
88
- </button>
89
- </div>
90
-
91
- <div class="mb-6">
92
- <div class="flex justify-between mb-2">
93
- <span class="text-sm font-medium text-gray-700">Прогресс рабочего дня</span>
94
- <span class="text-sm font-medium text-gray-700" id="work-progress">0%</span>
95
  </div>
96
- <div class="progress-bar">
97
- <div class="progress-fill" id="progress-fill" style="width: 0%"></div>
 
 
 
 
 
 
 
 
 
 
 
 
98
  </div>
99
  </div>
100
 
101
- <div class="grid grid-cols-3 gap-4 text-center">
102
- <div class="bg-gray-50 p-4 rounded-lg">
103
- <p class="text-sm text-gray-500">Отработано сегодня</p>
104
- <p class="text-2xl font-bold text-gray-800" id="today-hours">0 ч</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  </div>
106
- <div class="bg-gray-50 p-4 rounded-lg">
107
- <p class="text-sm text-gray-500">Отработано дней</p>
108
- <p class="text-2xl font-bold text-gray-800" id="worked-days">0</p>
 
109
  </div>
110
- <div class="bg-gray-50 p-4 rounded-lg">
111
- <p class="text-sm text-gray-500">Всего часов</p>
112
- <p class="text-2xl font-bold text-gray-800" id="total-hours">0 ч</p>
 
 
 
113
  </div>
114
  </div>
115
  </div>
116
 
117
- <div class="bg-white rounded-xl shadow-md p-6 mb-8">
118
- <div class="flex justify-between items-center mb-4">
119
- <h2 class="text-xl font-semibold text-gray-800">Статистика за месяц</h2>
120
- <div class="flex items-center">
121
- <button id="prev-month" class="p-2 rounded-full hover:bg-gray-100">
122
- <i class="fas fa-chevron-left text-gray-600"></i>
123
- </button>
124
- <span class="mx-4 font-medium" id="current-month">Июнь 2023</span>
125
- <button id="next-month" class="p-2 rounded-full hover:bg-gray-100">
126
- <i class="fas fa-chevron-right text-gray-600"></i>
127
- </button>
128
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  </div>
130
 
131
- <div class="overflow-x-auto">
132
- <table class="min-w-full divide-y divide-gray-200">
133
- <thead class="bg-gray-50">
134
- <tr>
135
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Дата</th>
136
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Начало</th>
137
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Конец</th>
138
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Часы</th>
139
- </tr>
140
- </thead>
141
- <tbody class="bg-white divide-y divide-gray-200" id="month-table-body">
142
- <!-- Данные будут добавляться сюда -->
143
- </tbody>
144
- </table>
145
- </div>
146
-
147
- <div class="mt-4 text-right">
148
- <p class="text-sm text-gray-500">Ито��о за месяц:</p>
149
- <p class="text-lg font-semibold" id="month-total">0 рабочих дней, 0 часов</p>
150
- </div>
151
- </div>
152
-
153
- <div class="bg-white rounded-xl shadow-md p-6">
154
- <h2 class="text-xl font-semibold text-gray-800 mb-4">История</h2>
155
- <div class="space-y-4" id="history-list">
156
- <!-- История будет добавляться сюда -->
157
  </div>
158
  </div>
159
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
  <script>
 
162
  document.addEventListener('DOMContentLoaded', function() {
163
  // Инициализация хранилища
164
- if (!localStorage.getItem('workTimeTracker')) {
165
- localStorage.setItem('workTimeTracker', JSON.stringify({
166
  currentSession: null,
167
  workDays: {},
168
- monthlyStats: {}
 
 
 
 
169
  }));
170
  }
171
 
172
- const appData = JSON.parse(localStorage.getItem('workTimeTracker'));
173
 
174
  // Элементы интерфейса
175
  const startBtn = document.getElementById('start-btn');
@@ -187,16 +265,28 @@
187
  const historyList = document.getElementById('history-list');
188
  const prevMonthBtn = document.getElementById('prev-month');
189
  const nextMonthBtn = document.getElementById('next-month');
 
 
 
 
 
 
 
 
190
 
191
  // Текущая дата и время
192
  const now = new Date();
193
  const today = formatDate(now);
194
- currentDate.textContent = `Сегодня: ${formatDate(now, true)}`;
195
 
196
  // Текущий месяц для статистики
197
  let currentMonthView = new Date(now.getFullYear(), now.getMonth(), 1);
198
  updateMonthView();
199
 
 
 
 
 
200
  // Проверка активной сессии
201
  if (appData.currentSession) {
202
  const sessionStart = new Date(appData.currentSession.startTime);
@@ -205,7 +295,7 @@
205
  startBtn.disabled = true;
206
  endBtn.disabled = false;
207
  currentStatus.textContent = 'Работаю';
208
- document.getElementById('start-btn').classList.remove('pulse');
209
 
210
  // Обновление таймера
211
  updateTimer();
@@ -235,16 +325,48 @@
235
  updateMonthView();
236
  });
237
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  // Обновление статистики
239
  updateStats();
240
 
241
  // Функции
242
- function formatDate(date, withWeekday = false) {
243
- const options = { year: 'numeric', month: '2-digit', day: '2-digit' };
244
- if (withWeekday) {
245
- options.weekday = 'long';
246
  }
247
- return date.toLocaleDateString('ru-RU', options);
248
  }
249
 
250
  function formatTime(date) {
@@ -258,15 +380,15 @@
258
  startTime: startTime.toISOString()
259
  };
260
 
261
- localStorage.setItem('workTimeTracker', JSON.stringify(appData));
262
 
263
  startBtn.disabled = true;
264
  endBtn.disabled = false;
265
  currentStatus.textContent = 'Работаю';
266
- document.getElementById('start-btn').classList.remove('pulse');
267
 
268
  // Добавление в историю
269
- addHistoryEvent('Начало рабочего дня', startTime);
270
 
271
  // Запуск таймера
272
  updateTimer();
@@ -276,6 +398,9 @@
276
  clearInterval(timerInterval);
277
  endWorkSession();
278
  });
 
 
 
279
  }
280
 
281
  function endWorkSession(customStartTime, customEndTime) {
@@ -309,12 +434,12 @@
309
 
310
  // Очистка текущей сессии
311
  appData.currentSession = null;
312
- localStorage.setItem('workTimeTracker', JSON.stringify(appData));
313
 
314
  startBtn.disabled = false;
315
  endBtn.disabled = true;
316
  currentStatus.textContent = 'Не начат';
317
- document.getElementById('start-btn').classList.add('pulse');
318
 
319
  // Сброс прогресса
320
  progressFill.style.width = '0%';
@@ -322,11 +447,14 @@
322
  todayHours.textContent = '0 ч';
323
 
324
  // Добавление в историю
325
- addHistoryEvent('Конец рабочего дня', endTime, durationHours);
326
 
327
  // Обновление статистики
328
  updateStats();
329
  updateMonthView();
 
 
 
330
  }
331
 
332
  function updateTimer() {
@@ -339,7 +467,8 @@
339
  todayHours.textContent = `${durationHours} ч`;
340
 
341
  // Расчет прогресса (8-часовой рабочий день)
342
- const progress = Math.min((durationMs / (8 * 60 * 60 * 1000)) * 100, 100);
 
343
  progressFill.style.width = `${progress}%`;
344
  workProgress.textContent = `${Math.round(progress)}%`;
345
  }
@@ -394,34 +523,41 @@
394
  row.className = 'fade-in';
395
 
396
  row.innerHTML = `
397
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">${formatDate(day.date)}</td>
398
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${formatTime(day.startTime)}</td>
399
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${formatTime(day.endTime)}</td>
400
- <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${day.duration} ч</td>
401
  `;
402
 
403
  monthTableBody.appendChild(row);
404
  });
405
 
 
 
 
 
 
 
 
 
 
406
  // Итого за месяц
407
- monthTotal.textContent = `${monthStats.days} рабочих дней, ${monthStats.hours.toFixed(1)} часов`;
408
  }
409
 
410
  function addHistoryEvent(event, time, duration = null) {
411
  const eventElement = document.createElement('div');
412
- eventElement.className = 'fade-in bg-gray-50 p-4 rounded-lg';
413
 
414
  let eventText = `
415
  <div class="flex justify-between items-center">
416
  <div>
417
- <p class="font-medium text-gray-800">${event}</p>
418
- <p class="text-sm text-gray-500">${formatTime(time)}</p>
419
  </div>
420
  `;
421
 
422
  if (duration) {
423
  eventText += `
424
- <span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded-full">
425
  ${duration} ч
426
  </span>
427
  `;
@@ -443,6 +579,36 @@
443
  }
444
  }
445
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
  // Загрузка истории
447
  function loadHistory() {
448
  historyList.innerHTML = '';
@@ -471,7 +637,7 @@
471
  // Отображение
472
  events.slice(0, 10).forEach(event => {
473
  addHistoryEvent(
474
- event.type === 'start' ? 'Начало рабочего дня' : 'Конец рабочего дня',
475
  event.time,
476
  event.duration
477
  );
@@ -479,6 +645,7 @@
479
  }
480
 
481
  loadHistory();
 
482
  });
483
  </script>
484
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=AliDu14/work-time" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>WorkTime Bot</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
+ body {
11
+ font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
12
+ background-color: var(--tg-theme-bg-color, #f7f8fc);
13
+ color: var(--tg-theme-text-color, #000000);
 
14
  }
15
 
16
+ .header {
17
+ background-color: var(--tg-theme-header-bg-color, #0088cc);
18
+ color: var(--tg-theme-header-text-color, #ffffff);
 
 
19
  }
20
 
21
+ .button-primary {
22
+ background-color: var(--tg-theme-button-color, #0088cc);
23
+ color: var(--tg-theme-button-text-color, #ffffff);
24
  }
25
 
26
+ .button-secondary {
27
+ background-color: var(--tg-theme-secondary-bg-color, #ebedf0);
28
+ color: var(--tg-theme-text-color, #000000);
29
+ }
30
+
31
+ .card {
32
+ background-color: var(--tg-theme-bg-color, #ffffff);
33
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
34
+ }
35
+
36
+ .progress-bar {
37
+ height: 6px;
38
+ border-radius: 3px;
39
+ background-color: var(--tg-theme-secondary-bg-color, #ebedf0);
40
  }
41
 
42
+ .progress-fill {
43
+ height: 100%;
44
+ border-radius: 3px;
45
+ background-color: var(--tg-theme-button-color, #0088cc);
46
+ transition: width 0.3s ease;
47
  }
48
 
49
  .pulse {
 
52
 
53
  @keyframes pulse {
54
  0% {
55
+ box-shadow: 0 0 0 0 rgba(0, 136, 204, 0.7);
56
  }
57
  70% {
58
+ box-shadow: 0 0 0 10px rgba(0, 136, 204, 0);
59
  }
60
  100% {
61
+ box-shadow: 0 0 0 0 rgba(0, 136, 204, 0);
62
  }
63
  }
64
 
65
  .fade-in {
66
+ animation: fadeIn 0.3s ease-in;
67
  }
68
 
69
  @keyframes fadeIn {
70
  from { opacity: 0; transform: translateY(10px); }
71
  to { opacity: 1; transform: translateY(0); }
72
  }
73
+
74
+ .telegram-input {
75
+ border: 1px solid var(--tg-theme-secondary-bg-color, #ebedf0);
76
+ background-color: var(--tg-theme-bg-color, #ffffff);
77
+ color: var(--tg-theme-text-color, #000000);
78
+ }
79
+
80
+ .telegram-hint {
81
+ color: var(--tg-theme-hint-color, #707579);
82
+ }
83
  </style>
84
  </head>
85
+ <body class="min-h-screen">
86
+ <div class="header px-4 py-3 flex items-center">
87
+ <button id="back-button" class="mr-3">
88
+ <i class="fas fa-chevron-left text-white"></i>
89
+ </button>
90
+ <h1 class="text-lg font-semibold">WorkTime Bot</h1>
91
+ </div>
92
+
93
+ <div class="container mx-auto px-4 py-3">
94
+ <!-- Основной экран -->
95
+ <div id="main-screen">
96
+ <div class="card rounded-xl p-4 mb-3">
97
+ <div class="flex justify-between items-center mb-3">
98
+ <div>
99
+ <h2 class="font-medium">Текущий статус</h2>
100
+ <p class="text-sm telegram-hint" id="current-date">Сегодня, 12 июня</p>
101
+ </div>
102
+ <div class="px-3 py-1 rounded-full bg-blue-100 text-blue-800 text-sm" id="current-status">
103
+ Не начат
104
+ </div>
105
  </div>
106
+
107
+ <div class="grid grid-cols-2 gap-2 mb-3">
108
+ <button id="start-btn" class="button-primary pulse rounded-lg py-3 px-4 font-medium flex items-center justify-center">
109
+ <i class="fas fa-play mr-2"></i> Старт
110
+ </button>
111
+ <button id="end-btn" class="button-secondary rounded-lg py-3 px-4 font-medium flex items-center justify-center" disabled>
112
+ <i class="fas fa-stop mr-2"></i> Стоп
113
+ </button>
114
  </div>
115
+
116
+ <div class="mb-3">
117
+ <div class="flex justify-between mb-1">
118
+ <span class="text-sm telegram-hint">Прогресс дня</span>
119
+ <span class="text-sm font-medium" id="work-progress">0%</span>
120
+ </div>
121
+ <div class="progress-bar">
122
+ <div class="progress-fill" id="progress-fill" style="width: 0%"></div>
123
+ </div>
 
 
 
 
 
 
124
  </div>
125
+
126
+ <div class="grid grid-cols-3 gap-2 text-center">
127
+ <div class="rounded-lg p-2 bg-blue-50">
128
+ <p class="text-xs telegram-hint">Сегодня</p>
129
+ <p class="font-bold" id="today-hours">0 ч</p>
130
+ </div>
131
+ <div class="rounded-lg p-2 bg-blue-50">
132
+ <p class="text-xs telegram-hint">Дней</p>
133
+ <p class="font-bold" id="worked-days">0</p>
134
+ </div>
135
+ <div class="rounded-lg p-2 bg-blue-50">
136
+ <p class="text-xs telegram-hint">Всего</p>
137
+ <p class="font-bold" id="total-hours">0 ч</p>
138
+ </div>
139
  </div>
140
  </div>
141
 
142
+ <div class="card rounded-xl p-4 mb-3">
143
+ <div class="flex justify-between items-center mb-3">
144
+ <h2 class="font-medium">Статистика</h2>
145
+ <div class="flex items-center">
146
+ <button id="prev-month" class="p-1 rounded-full hover:bg-gray-100">
147
+ <i class="fas fa-chevron-left telegram-hint"></i>
148
+ </button>
149
+ <span class="mx-2 text-sm font-medium" id="current-month">Июнь 2023</span>
150
+ <button id="next-month" class="p-1 rounded-full hover:bg-gray-100">
151
+ <i class="fas fa-chevron-right telegram-hint"></i>
152
+ </button>
153
+ </div>
154
+ </div>
155
+
156
+ <div class="overflow-hidden rounded-lg">
157
+ <table class="min-w-full">
158
+ <thead class="bg-gray-100">
159
+ <tr>
160
+ <th class="px-3 py-2 text-left text-xs font-medium telegram-hint">Дата</th>
161
+ <th class="px-3 py-2 text-left text-xs font-medium telegram-hint">Часы</th>
162
+ </tr>
163
+ </thead>
164
+ <tbody class="divide-y divide-gray-200" id="month-table-body">
165
+ <!-- Данные будут добавляться сюда -->
166
+ </tbody>
167
+ </table>
168
  </div>
169
+
170
+ <div class="mt-3 pt-2 border-t border-gray-200 text-right">
171
+ <p class="text-xs telegram-hint">Итого за месяц:</p>
172
+ <p class="text-sm font-medium" id="month-total">0 дней, 0 часов</p>
173
  </div>
174
+ </div>
175
+
176
+ <div class="card rounded-xl p-4">
177
+ <h2 class="font-medium mb-3">История</h2>
178
+ <div class="space-y-2" id="history-list">
179
+ <!-- История будет добавляться сюда -->
180
  </div>
181
  </div>
182
  </div>
183
 
184
+ <!-- Экран настроек -->
185
+ <div id="settings-screen" class="hidden">
186
+ <div class="card rounded-xl p-4 mb-3">
187
+ <h2 class="font-medium mb-3">Настройки</h2>
188
+
189
+ <div class="mb-3">
190
+ <label class="block text-sm font-medium mb-1">Рабочих часов в день</label>
191
+ <input type="number" id="work-hours-per-day" class="telegram-input w-full rounded-lg px-3 py-2" value="8" min="1" max="24">
 
 
 
192
  </div>
193
+
194
+ <div class="mb-3">
195
+ <label class="block text-sm font-medium mb-1">Уведомления</label>
196
+ <div class="flex items-center justify-between">
197
+ <span class="text-sm">Напоминать о перерывах</span>
198
+ <label class="relative inline-flex items-center cursor-pointer">
199
+ <input type="checkbox" id="break-reminders" class="sr-only peer">
200
+ <div class="w-9 h-5 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-blue-600"></div>
201
+ </label>
202
+ </div>
203
+ </div>
204
+
205
+ <button id="save-settings" class="button-primary w-full rounded-lg py-3 px-4 font-medium">
206
+ Сохранить
207
+ </button>
208
  </div>
209
 
210
+ <div class="card rounded-xl p-4">
211
+ <h2 class="font-medium mb-3">О боте</h2>
212
+ <p class="text-sm mb-2">WorkTime Bot v1.0</p>
213
+ <p class="text-sm telegram-hint">Отслеживайте свое рабочее время прямо в Telegram</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  </div>
215
  </div>
216
  </div>
217
+
218
+ <!-- Нижнее меню -->
219
+ <div class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 flex justify-around py-2">
220
+ <button id="main-tab" class="flex flex-col items-center px-4 py-1 text-blue-600">
221
+ <i class="fas fa-home"></i>
222
+ <span class="text-xs mt-1">Главная</span>
223
+ </button>
224
+ <button id="stats-tab" class="flex flex-col items-center px-4 py-1 text-gray-500">
225
+ <i class="fas fa-chart-bar"></i>
226
+ <span class="text-xs mt-1">Статистика</span>
227
+ </button>
228
+ <button id="settings-tab" class="flex flex-col items-center px-4 py-1 text-gray-500">
229
+ <i class="fas fa-cog"></i>
230
+ <span class="text-xs mt-1">Настройки</span>
231
+ </button>
232
+ </div>
233
 
234
  <script>
235
+ // Имитация Telegram WebApp
236
  document.addEventListener('DOMContentLoaded', function() {
237
  // Инициализация хранилища
238
+ if (!localStorage.getItem('workTimeBot')) {
239
+ localStorage.setItem('workTimeBot', JSON.stringify({
240
  currentSession: null,
241
  workDays: {},
242
+ monthlyStats: {},
243
+ settings: {
244
+ workHoursPerDay: 8,
245
+ breakReminders: true
246
+ }
247
  }));
248
  }
249
 
250
+ const appData = JSON.parse(localStorage.getItem('workTimeBot'));
251
 
252
  // Элементы интерфейса
253
  const startBtn = document.getElementById('start-btn');
 
265
  const historyList = document.getElementById('history-list');
266
  const prevMonthBtn = document.getElementById('prev-month');
267
  const nextMonthBtn = document.getElementById('next-month');
268
+ const mainScreen = document.getElementById('main-screen');
269
+ const settingsScreen = document.getElementById('settings-screen');
270
+ const mainTab = document.getElementById('main-tab');
271
+ const settingsTab = document.getElementById('settings-tab');
272
+ const workHoursInput = document.getElementById('work-hours-per-day');
273
+ const breakRemindersToggle = document.getElementById('break-reminders');
274
+ const saveSettingsBtn = document.getElementById('save-settings');
275
+ const backButton = document.getElementById('back-button');
276
 
277
  // Текущая дата и время
278
  const now = new Date();
279
  const today = formatDate(now);
280
+ currentDate.textContent = `Сегодня, ${formatDate(now, true)}`;
281
 
282
  // Текущий месяц для статистики
283
  let currentMonthView = new Date(now.getFullYear(), now.getMonth(), 1);
284
  updateMonthView();
285
 
286
+ // Загрузка настроек
287
+ workHoursInput.value = appData.settings.workHoursPerDay;
288
+ breakRemindersToggle.checked = appData.settings.breakReminders;
289
+
290
  // Проверка активной сессии
291
  if (appData.currentSession) {
292
  const sessionStart = new Date(appData.currentSession.startTime);
 
295
  startBtn.disabled = true;
296
  endBtn.disabled = false;
297
  currentStatus.textContent = 'Работаю';
298
+ startBtn.classList.remove('pulse');
299
 
300
  // Обновление таймера
301
  updateTimer();
 
325
  updateMonthView();
326
  });
327
 
328
+ // Переключение экранов
329
+ settingsTab.addEventListener('click', function() {
330
+ mainScreen.classList.add('hidden');
331
+ settingsScreen.classList.remove('hidden');
332
+ updateTabStyles('settings');
333
+ });
334
+
335
+ mainTab.addEventListener('click', function() {
336
+ mainScreen.classList.remove('hidden');
337
+ settingsScreen.classList.add('hidden');
338
+ updateTabStyles('main');
339
+ });
340
+
341
+ backButton.addEventListener('click', function() {
342
+ // В реальном боте это закрыло бы веб-приложение
343
+ alert('В реальном Telegram боте это закрыло бы веб-приложение');
344
+ });
345
+
346
+ // Сохранение настроек
347
+ saveSettingsBtn.addEventListener('click', function() {
348
+ appData.settings.workHoursPerDay = parseInt(workHoursInput.value) || 8;
349
+ appData.settings.breakReminders = breakRemindersToggle.checked;
350
+ localStorage.setItem('workTimeBot', JSON.stringify(appData));
351
+
352
+ // Возврат на главный экран
353
+ mainScreen.classList.remove('hidden');
354
+ settingsScreen.classList.add('hidden');
355
+ updateTabStyles('main');
356
+
357
+ // Показ уведомления
358
+ showTelegramNotification('Настройки сохранены');
359
+ });
360
+
361
  // Обновление статистики
362
  updateStats();
363
 
364
  // Функции
365
+ function formatDate(date, short = false) {
366
+ if (short) {
367
+ return date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long' });
 
368
  }
369
+ return date.toLocaleDateString('ru-RU');
370
  }
371
 
372
  function formatTime(date) {
 
380
  startTime: startTime.toISOString()
381
  };
382
 
383
+ localStorage.setItem('workTimeBot', JSON.stringify(appData));
384
 
385
  startBtn.disabled = true;
386
  endBtn.disabled = false;
387
  currentStatus.textContent = 'Работаю';
388
+ startBtn.classList.remove('pulse');
389
 
390
  // Добавление в историю
391
+ addHistoryEvent('Начало работы', startTime);
392
 
393
  // Запуск таймера
394
  updateTimer();
 
398
  clearInterval(timerInterval);
399
  endWorkSession();
400
  });
401
+
402
+ // Имитация уведомления Telegram
403
+ showTelegramNotification('Рабочий день начат');
404
  }
405
 
406
  function endWorkSession(customStartTime, customEndTime) {
 
434
 
435
  // Очистка текущей сессии
436
  appData.currentSession = null;
437
+ localStorage.setItem('workTimeBot', JSON.stringify(appData));
438
 
439
  startBtn.disabled = false;
440
  endBtn.disabled = true;
441
  currentStatus.textContent = 'Не начат';
442
+ startBtn.classList.add('pulse');
443
 
444
  // Сброс прогресса
445
  progressFill.style.width = '0%';
 
447
  todayHours.textContent = '0 ч';
448
 
449
  // Добавление в историю
450
+ addHistoryEvent('Конец работы', endTime, durationHours);
451
 
452
  // Обновление статистики
453
  updateStats();
454
  updateMonthView();
455
+
456
+ // Имитация уведомления Telegram
457
+ showTelegramNotification(`Рабочий день завершен: ${durationHours} ч`);
458
  }
459
 
460
  function updateTimer() {
 
467
  todayHours.textContent = `${durationHours} ч`;
468
 
469
  // Расчет прогресса (8-часовой рабочий день)
470
+ const workHoursPerDay = appData.settings.workHoursPerDay || 8;
471
+ const progress = Math.min((durationMs / (workHoursPerDay * 60 * 60 * 1000)) * 100, 100);
472
  progressFill.style.width = `${progress}%`;
473
  workProgress.textContent = `${Math.round(progress)}%`;
474
  }
 
523
  row.className = 'fade-in';
524
 
525
  row.innerHTML = `
526
+ <td class="px-3 py-2 text-sm">${formatDate(day.date)}</td>
527
+ <td class="px-3 py-2 text-sm font-medium">${day.duration} ч</td>
 
 
528
  `;
529
 
530
  monthTableBody.appendChild(row);
531
  });
532
 
533
+ // Если нет данных за месяц
534
+ if (monthWorkDays.length === 0) {
535
+ const row = document.createElement('tr');
536
+ row.innerHTML = `
537
+ <td colspan="2" class="px-3 py-4 text-center text-sm telegram-hint">Нет данных за этот месяц</td>
538
+ `;
539
+ monthTableBody.appendChild(row);
540
+ }
541
+
542
  // Итого за месяц
543
+ monthTotal.textContent = `${monthStats.days} дней, ${monthStats.hours.toFixed(1)} часов`;
544
  }
545
 
546
  function addHistoryEvent(event, time, duration = null) {
547
  const eventElement = document.createElement('div');
548
+ eventElement.className = 'fade-in p-3 rounded-lg bg-gray-100';
549
 
550
  let eventText = `
551
  <div class="flex justify-between items-center">
552
  <div>
553
+ <p class="font-medium">${event}</p>
554
+ <p class="text-xs telegram-hint">${formatTime(time)}</p>
555
  </div>
556
  `;
557
 
558
  if (duration) {
559
  eventText += `
560
+ <span class="bg-blue-100 text-blue-800 text-xs font-medium px-2 py-0.5 rounded-full">
561
  ${duration} ч
562
  </span>
563
  `;
 
579
  }
580
  }
581
 
582
+ function updateTabStyles(activeTab) {
583
+ const tabs = ['main', 'stats', 'settings'];
584
+ tabs.forEach(tab => {
585
+ const tabElement = document.getElementById(`${tab}-tab`);
586
+ if (tab === activeTab) {
587
+ tabElement.classList.remove('text-gray-500');
588
+ tabElement.classList.add('text-blue-600');
589
+ } else {
590
+ tabElement.classList.remove('text-blue-600');
591
+ tabElement.classList.add('text-gray-500');
592
+ }
593
+ });
594
+ }
595
+
596
+ function showTelegramNotification(message) {
597
+ // В реальном Telegram WebApp можно использовать window.Telegram.WebApp.showAlert(message);
598
+ console.log('Telegram notification:', message);
599
+
600
+ // Визуальная имитация уведомления
601
+ const notification = document.createElement('div');
602
+ notification.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-4 py-2 rounded-lg shadow-lg text-sm fade-in';
603
+ notification.textContent = message;
604
+ document.body.appendChild(notification);
605
+
606
+ setTimeout(() => {
607
+ notification.classList.add('opacity-0', 'transition-opacity', 'duration-300');
608
+ setTimeout(() => notification.remove(), 300);
609
+ }, 3000);
610
+ }
611
+
612
  // Загрузка истории
613
  function loadHistory() {
614
  historyList.innerHTML = '';
 
637
  // Отображение
638
  events.slice(0, 10).forEach(event => {
639
  addHistoryEvent(
640
+ event.type === 'start' ? 'Начало работы' : 'Конец работы',
641
  event.time,
642
  event.duration
643
  );
 
645
  }
646
 
647
  loadHistory();
648
+ updateTabStyles('main');
649
  });
650
  </script>
651
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=AliDu14/work-time" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>