Barton0708 commited on
Commit
9ce28e1
·
verified ·
1 Parent(s): 4a2026f

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +1064 -19
index.html CHANGED
@@ -1,19 +1,1064 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ru">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>🌊 Karnet Manager Pro v3.0 - Морской интерфейс</title>
7
+ <style>
8
+ :root {
9
+ --sea-bg: #f0f8ff;
10
+ --sea-fg: #2f4f4f;
11
+ --sea-accent: #4682b4;
12
+ --sea-success: #20b2aa;
13
+ --sea-warning: #daa520;
14
+ --sea-error: #cd5c5c;
15
+ --sea-button: #e0f6ff;
16
+ --sea-button-hover: #87ceeb;
17
+ --sea-frame: #f5f5f5;
18
+ --sea-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
19
+ --sea-transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
20
+ }
21
+
22
+ * {
23
+ margin: 0;
24
+ padding: 0;
25
+ box-sizing: border-box;
26
+ }
27
+
28
+ body {
29
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
30
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
31
+ min-height: 100vh;
32
+ color: var(--sea-fg);
33
+ position: relative;
34
+ }
35
+
36
+ body::before {
37
+ content: '';
38
+ position: fixed;
39
+ top: 0;
40
+ left: 0;
41
+ right: 0;
42
+ bottom: 0;
43
+ background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%234682b4" fill-opacity="0.1" d="M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,122.7C672,117,768,139,864,138.7C960,139,1056,117,1152,106.7C1248,96,1344,96,1392,96L1440,96L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>') no-repeat bottom;
44
+ background-size: cover;
45
+ pointer-events: none;
46
+ opacity: 0.3;
47
+ }
48
+
49
+ .container {
50
+ max-width: 1400px;
51
+ margin: 0 auto;
52
+ padding: 20px;
53
+ position: relative;
54
+ z-index: 1;
55
+ }
56
+
57
+ header {
58
+ background: rgba(255, 255, 255, 0.95);
59
+ backdrop-filter: blur(10px);
60
+ border-radius: 20px;
61
+ padding: 25px;
62
+ margin-bottom: 30px;
63
+ box-shadow: var(--sea-shadow);
64
+ animation: slideDown 0.5s ease-out;
65
+ }
66
+
67
+ @keyframes slideDown {
68
+ from {
69
+ transform: translateY(-20px);
70
+ opacity: 0;
71
+ }
72
+ to {
73
+ transform: translateY(0);
74
+ opacity: 1;
75
+ }
76
+ }
77
+
78
+ h1 {
79
+ color: var(--sea-accent);
80
+ font-size: 2.5em;
81
+ margin-bottom: 10px;
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 15px;
85
+ }
86
+
87
+ .subtitle {
88
+ color: var(--sea-fg);
89
+ font-size: 1.1em;
90
+ opacity: 0.8;
91
+ }
92
+
93
+ .tabs {
94
+ display: flex;
95
+ gap: 10px;
96
+ margin-bottom: 30px;
97
+ flex-wrap: wrap;
98
+ background: rgba(255, 255, 255, 0.9);
99
+ padding: 10px;
100
+ border-radius: 15px;
101
+ box-shadow: var(--sea-shadow);
102
+ }
103
+
104
+ .tab-button {
105
+ padding: 12px 24px;
106
+ background: var(--sea-button);
107
+ border: none;
108
+ border-radius: 10px;
109
+ cursor: pointer;
110
+ font-size: 1em;
111
+ font-weight: 600;
112
+ color: var(--sea-fg);
113
+ transition: var(--sea-transition);
114
+ position: relative;
115
+ overflow: hidden;
116
+ }
117
+
118
+ .tab-button::before {
119
+ content: '';
120
+ position: absolute;
121
+ top: 0;
122
+ left: -100%;
123
+ width: 100%;
124
+ height: 100%;
125
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
126
+ transition: left 0.5s;
127
+ }
128
+
129
+ .tab-button:hover::before {
130
+ left: 100%;
131
+ }
132
+
133
+ .tab-button:hover {
134
+ background: var(--sea-button-hover);
135
+ transform: translateY(-2px);
136
+ box-shadow: 0 6px 12px rgba(70, 130, 180, 0.3);
137
+ }
138
+
139
+ .tab-button.active {
140
+ background: var(--sea-accent);
141
+ color: white;
142
+ }
143
+
144
+ .tab-content {
145
+ display: none;
146
+ background: rgba(255, 255, 255, 0.95);
147
+ backdrop-filter: blur(10px);
148
+ border-radius: 20px;
149
+ padding: 30px;
150
+ box-shadow: var(--sea-shadow);
151
+ animation: fadeIn 0.5s ease-out;
152
+ }
153
+
154
+ .tab-content.active {
155
+ display: block;
156
+ }
157
+
158
+ @keyframes fadeIn {
159
+ from {
160
+ opacity: 0;
161
+ transform: translateY(10px);
162
+ }
163
+ to {
164
+ opacity: 1;
165
+ transform: translateY(0);
166
+ }
167
+ }
168
+
169
+ .form-group {
170
+ margin-bottom: 25px;
171
+ }
172
+
173
+ label {
174
+ display: block;
175
+ margin-bottom: 8px;
176
+ font-weight: 600;
177
+ color: var(--sea-fg);
178
+ }
179
+
180
+ input[type="text"],
181
+ input[type="email"],
182
+ select,
183
+ textarea {
184
+ width: 100%;
185
+ padding: 12px;
186
+ border: 2px solid #e0e0e0;
187
+ border-radius: 10px;
188
+ font-size: 1em;
189
+ transition: var(--sea-transition);
190
+ background: white;
191
+ }
192
+
193
+ input:focus,
194
+ select:focus,
195
+ textarea:focus {
196
+ outline: none;
197
+ border-color: var(--sea-accent);
198
+ box-shadow: 0 0 0 3px rgba(70, 130, 180, 0.1);
199
+ }
200
+
201
+ .button-group {
202
+ display: flex;
203
+ gap: 15px;
204
+ flex-wrap: wrap;
205
+ margin-top: 20px;
206
+ }
207
+
208
+ button {
209
+ padding: 12px 24px;
210
+ background: var(--sea-accent);
211
+ color: white;
212
+ border: none;
213
+ border-radius: 10px;
214
+ cursor: pointer;
215
+ font-size: 1em;
216
+ font-weight: 600;
217
+ transition: var(--sea-transition);
218
+ position: relative;
219
+ overflow: hidden;
220
+ }
221
+
222
+ button::after {
223
+ content: '';
224
+ position: absolute;
225
+ top: 50%;
226
+ left: 50%;
227
+ width: 0;
228
+ height: 0;
229
+ border-radius: 50%;
230
+ background: rgba(255, 255, 255, 0.5);
231
+ transform: translate(-50%, -50%);
232
+ transition: width 0.6s, height 0.6s;
233
+ }
234
+
235
+ button:hover::after {
236
+ width: 300px;
237
+ height: 300px;
238
+ }
239
+
240
+ button:hover {
241
+ background: var(--sea-button-hover);
242
+ transform: translateY(-2px);
243
+ box-shadow: 0 6px 12px rgba(70, 130, 180, 0.3);
244
+ }
245
+
246
+ button:active {
247
+ transform: translateY(0);
248
+ }
249
+
250
+ button.secondary {
251
+ background: var(--sea-button);
252
+ color: var(--sea-fg);
253
+ }
254
+
255
+ button.success {
256
+ background: var(--sea-success);
257
+ }
258
+
259
+ button.warning {
260
+ background: var(--sea-warning);
261
+ }
262
+
263
+ button.error {
264
+ background: var(--sea-error);
265
+ }
266
+
267
+ .log-container {
268
+ background: #1e1e1e;
269
+ color: #00ff00;
270
+ padding: 20px;
271
+ border-radius: 10px;
272
+ font-family: 'Consolas', 'Monaco', monospace;
273
+ font-size: 0.9em;
274
+ height: 300px;
275
+ overflow-y: auto;
276
+ margin-top: 20px;
277
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
278
+ }
279
+
280
+ .log-entry {
281
+ margin-bottom: 5px;
282
+ padding: 5px;
283
+ border-radius: 3px;
284
+ transition: background 0.2s;
285
+ }
286
+
287
+ .log-entry:hover {
288
+ background: rgba(255, 255, 255, 0.05);
289
+ }
290
+
291
+ .log-entry.info {
292
+ color: #87ceeb;
293
+ }
294
+
295
+ .log-entry.success {
296
+ color: #90ee90;
297
+ }
298
+
299
+ .log-entry.warning {
300
+ color: #ffd700;
301
+ }
302
+
303
+ .log-entry.error {
304
+ color: #ff6b6b;
305
+ }
306
+
307
+ .status-bar {
308
+ position: fixed;
309
+ bottom: 0;
310
+ left: 0;
311
+ right: 0;
312
+ background: var(--sea-accent);
313
+ color: white;
314
+ padding: 15px 30px;
315
+ display: flex;
316
+ justify-content: space-between;
317
+ align-items: center;
318
+ box-shadow: 0 -4px 6px rgba(0, 0, 0, 0.1);
319
+ z-index: 1000;
320
+ }
321
+
322
+ .status-message {
323
+ font-weight: 600;
324
+ display: flex;
325
+ align-items: center;
326
+ gap: 10px;
327
+ }
328
+
329
+ .progress-bar {
330
+ width: 200px;
331
+ height: 6px;
332
+ background: rgba(255, 255, 255, 0.3);
333
+ border-radius: 3px;
334
+ overflow: hidden;
335
+ }
336
+
337
+ .progress-fill {
338
+ height: 100%;
339
+ background: white;
340
+ border-radius: 3px;
341
+ animation: progress 2s ease-in-out infinite;
342
+ }
343
+
344
+ @keyframes progress {
345
+ 0% { width: 0%; }
346
+ 50% { width: 70%; }
347
+ 100% { width: 0%; }
348
+ }
349
+
350
+ .file-list {
351
+ background: var(--sea-frame);
352
+ border-radius: 10px;
353
+ padding: 15px;
354
+ margin-top: 15px;
355
+ max-height: 200px;
356
+ overflow-y: auto;
357
+ }
358
+
359
+ .file-item {
360
+ padding: 10px;
361
+ background: white;
362
+ border-radius: 8px;
363
+ margin-bottom: 10px;
364
+ display: flex;
365
+ justify-content: space-between;
366
+ align-items: center;
367
+ transition: var(--sea-transition);
368
+ }
369
+
370
+ .file-item:hover {
371
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
372
+ transform: translateX(5px);
373
+ }
374
+
375
+ .checkbox-group {
376
+ display: flex;
377
+ gap: 20px;
378
+ margin: 15px 0;
379
+ flex-wrap: wrap;
380
+ }
381
+
382
+ .checkbox-wrapper {
383
+ display: flex;
384
+ align-items: center;
385
+ gap: 8px;
386
+ }
387
+
388
+ input[type="checkbox"] {
389
+ width: 20px;
390
+ height: 20px;
391
+ cursor: pointer;
392
+ }
393
+
394
+ .stats-grid {
395
+ display: grid;
396
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
397
+ gap: 20px;
398
+ margin-top: 20px;
399
+ }
400
+
401
+ .stat-card {
402
+ background: linear-gradient(135deg, var(--sea-accent), var(--sea-button-hover));
403
+ color: white;
404
+ padding: 20px;
405
+ border-radius: 15px;
406
+ text-align: center;
407
+ transition: var(--sea-transition);
408
+ }
409
+
410
+ .stat-card:hover {
411
+ transform: translateY(-5px);
412
+ box-shadow: 0 10px 20px rgba(70, 130, 180, 0.3);
413
+ }
414
+
415
+ .stat-number {
416
+ font-size: 2.5em;
417
+ font-weight: bold;
418
+ margin-bottom: 5px;
419
+ }
420
+
421
+ .stat-label {
422
+ font-size: 0.9em;
423
+ opacity: 0.9;
424
+ }
425
+
426
+ .modal {
427
+ display: none;
428
+ position: fixed;
429
+ top: 0;
430
+ left: 0;
431
+ right: 0;
432
+ bottom: 0;
433
+ background: rgba(0, 0, 0, 0.5);
434
+ z-index: 2000;
435
+ animation: fadeIn 0.3s;
436
+ }
437
+
438
+ .modal.active {
439
+ display: flex;
440
+ justify-content: center;
441
+ align-items: center;
442
+ }
443
+
444
+ .modal-content {
445
+ background: white;
446
+ border-radius: 20px;
447
+ padding: 30px;
448
+ max-width: 500px;
449
+ width: 90%;
450
+ animation: slideUp 0.3s;
451
+ }
452
+
453
+ @keyframes slideUp {
454
+ from {
455
+ transform: translateY(20px);
456
+ opacity: 0;
457
+ }
458
+ to {
459
+ transform: translateY(0);
460
+ opacity: 1;
461
+ }
462
+ }
463
+
464
+ .toast {
465
+ position: fixed;
466
+ top: 20px;
467
+ right: 20px;
468
+ padding: 15px 20px;
469
+ border-radius: 10px;
470
+ color: white;
471
+ font-weight: 600;
472
+ z-index: 3000;
473
+ animation: slideInRight 0.3s;
474
+ display: none;
475
+ }
476
+
477
+ .toast.show {
478
+ display: block;
479
+ }
480
+
481
+ .toast.success {
482
+ background: var(--sea-success);
483
+ }
484
+
485
+ .toast.error {
486
+ background: var(--sea-error);
487
+ }
488
+
489
+ .toast.warning {
490
+ background: var(--sea-warning);
491
+ }
492
+
493
+ .toast.info {
494
+ background: var(--sea-accent);
495
+ }
496
+
497
+ @keyframes slideInRight {
498
+ from {
499
+ transform: translateX(100%);
500
+ opacity: 0;
501
+ }
502
+ to {
503
+ transform: translateX(0);
504
+ opacity: 1;
505
+ }
506
+ }
507
+
508
+ .file-input-wrapper {
509
+ position: relative;
510
+ overflow: hidden;
511
+ display: inline-block;
512
+ width: 100%;
513
+ }
514
+
515
+ .file-input-wrapper input[type=file] {
516
+ position: absolute;
517
+ left: -9999px;
518
+ }
519
+
520
+ .file-input-label {
521
+ display: block;
522
+ padding: 12px;
523
+ background: var(--sea-button);
524
+ border: 2px dashed var(--sea-accent);
525
+ border-radius: 10px;
526
+ text-align: center;
527
+ cursor: pointer;
528
+ transition: var(--sea-transition);
529
+ }
530
+
531
+ .file-input-label:hover {
532
+ background: var(--sea-button-hover);
533
+ border-style: solid;
534
+ }
535
+
536
+ @media (max-width: 768px) {
537
+ .container {
538
+ padding: 10px;
539
+ }
540
+
541
+ h1 {
542
+ font-size: 1.8em;
543
+ }
544
+
545
+ .tabs {
546
+ justify-content: center;
547
+ }
548
+
549
+ .tab-button {
550
+ padding: 10px 16px;
551
+ font-size: 0.9em;
552
+ }
553
+
554
+ .button-group {
555
+ flex-direction: column;
556
+ }
557
+
558
+ button {
559
+ width: 100%;
560
+ }
561
+
562
+ .stats-grid {
563
+ grid-template-columns: 1fr;
564
+ }
565
+ }
566
+
567
+ .loader {
568
+ border: 3px solid #f3f3f3;
569
+ border-top: 3px solid var(--sea-accent);
570
+ border-radius: 50%;
571
+ width: 40px;
572
+ height: 40px;
573
+ animation: spin 1s linear infinite;
574
+ margin: 20px auto;
575
+ }
576
+
577
+ @keyframes spin {
578
+ 0% { transform: rotate(0deg); }
579
+ 100% { transform: rotate(360deg); }
580
+ }
581
+
582
+ .floating {
583
+ animation: floating 3s ease-in-out infinite;
584
+ }
585
+
586
+ @keyframes floating {
587
+ 0% { transform: translateY(0px); }
588
+ 50% { transform: translateY(-10px); }
589
+ 100% { transform: translateY(0px); }
590
+ }
591
+ </style>
592
+ </head>
593
+ <body>
594
+ <div class="container">
595
+ <header>
596
+ <h1>
597
+ <span class="floating">🌊</span>
598
+ Karnet Manager Pro v3.0
599
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="font-size: 0.4em; color: var(--sea-accent); text-decoration: none;">Built with anycoder</a>
600
+ </h1>
601
+ <p class="subtitle">Морской интерфейс для управления карнетами</p>
602
+ </header>
603
+
604
+ <nav class="tabs">
605
+ <button class="tab-button active" onclick="switchTab('email')">
606
+ 📧 Email Manager
607
+ </button>
608
+ <button class="tab-button" onclick="switchTab('karnet')">
609
+ 📊 Karnet Manager Pro
610
+ </button>
611
+ <button class="tab-button" onclick="switchTab('daily')">
612
+ 📅 Ежедневный Учет
613
+ </button>
614
+ <button class="tab-button" onclick="switchTab('settings')">
615
+ ⚙️ Настройки
616
+ </button>
617
+ </nav>
618
+
619
+ <main>
620
+ <!-- Email Manager Tab -->
621
+ <div id="email" class="tab-content active">
622
+ <h2>📧 Outlook Attachment Saver</h2>
623
+
624
+ <div class="form-group">
625
+ <label for="email">📧 Email:</label>
626
+ <input type="email" id="email" placeholder="Введите email адрес">
627
+ </div>
628
+
629
+ <div class="button-group">
630
+ <button onclick="runOutlookSaver()">
631
+ 🚀 Запустить OutlookAttachmentSaver
632
+ </button>
633
+ <button class="secondary" onclick="saveEmail()">
634
+ 💾 Сохранить Email
635
+ </button>
636
+ </div>
637
+
638
+ <h3 style="margin-top: 30px;">📋 Лог операций</h3>
639
+ <div id="emailLog" class="log-container"></div>
640
+ </div>
641
+
642
+ <!-- Karnet Manager Pro Tab -->
643
+ <div id="karnet" class="tab-content">
644
+ <h2>📊 Karnet Manager Pro</h2>
645
+
646
+ <div class="form-group">
647
+ <label for="karnetFolder">📁 Папка с Excel файлами:</label>
648
+ <div style="display: flex; gap: 10px;">
649
+ <input type="text" id="karnetFolder" placeholder="Выберите папку с файлами">
650
+ <button onclick="browseFolder()">📁 Обзор</button>
651
+ </div>
652
+ </div>
653
+
654
+ <div class="form-group">
655
+ <label>🔍 Управление шаблоном</label>
656
+ <div style="background: var(--sea-frame); padding: 15px; border-radius: 10px;">
657
+ <p id="templateInfo">📋 Мастер-шаблон: Шаблоны/Книга5_fixed.xlsx</p>
658
+ <div class="button-group" style="margin-top: 15px;">
659
+ <button onclick="checkTemplate()">🔍 Проверить шаблон</button>
660
+ <button class="success" onclick="createTemplate()">🛠️ Создать шаблон</button>
661
+ </div>
662
+ </div>
663
+ </div>
664
+
665
+ <div class="form-group">
666
+ <label>⚡ Быстрая обработка файлов</label>
667
+ <div class="file-input-wrapper">
668
+ <input type="file" id="quickFiles" multiple accept=".xlsx,.xlsb">
669
+ <label for="quickFiles" class="file-input-label">
670
+ 📁 Выберите файлы для быстрой обработки
671
+ </label>
672
+ </div>
673
+ <div id="quickFilesList" class="file-list"></div>
674
+
675
+ <div class="checkbox-group">
676
+ <div class="checkbox-wrapper">
677
+ <input type="checkbox" id="quickToTarget" checked>
678
+ <label for="quickToTarget">в Целевой файл</label>
679
+ </div>
680
+ <div class="checkbox-wrapper">
681
+ <input type="checkbox" id="quickToNew">
682
+ <label for="quickToNew">в Новый файл</label>
683
+ </div>
684
+ </div>
685
+
686
+ <div class="button-group">
687
+ <button onclick="quickProcessFiles()">⚡ Обработать</button>
688
+ <button class="secondary" onclick="clearQuickFiles()">🗑️ Очистить</button>
689
+ </div>
690
+ </div>
691
+
692
+ <div class="form-group">
693
+ <label for="targetFile">🎯 Целевой файл:</label>
694
+ <div style="display: flex; gap: 10px;">
695
+ <input type="text" id="targetFile" placeholder="Выберите целевой файл">
696
+ <button onclick="browseTargetFile()">📄 Выбрать</button>
697
+ </div>
698
+
699
+ <div class="checkbox-group">
700
+ <div class="checkbox-wrapper">
701
+ <input type="checkbox" id="headerPresent" checked>
702
+ <label for="headerPresent">Заголовки есть</label>
703
+ </div>
704
+ <div class="checkbox-wrapper">
705
+ <input type="checkbox" id="headerAbsent">
706
+ <label for="headerAbsent">Заголовков нет</label>
707
+ </div>
708
+ </div>
709
+
710
+ <div class="button-group">
711
+ <button onclick="mergeKarnets()">⚡ Обработать</button>
712
+ <button class="secondary" onclick="clearTargetFile()">🗑️ Очистить</button>
713
+ <button class="success" onclick="mergeKarnetsToNewFile()">
714
+ 📥 Объединить в новый файл
715
+ </button>
716
+ </div>
717
+ </div>
718
+
719
+ <div class="stats-grid">
720
+ <div class="stat-card">
721
+ <div class="stat-number" id="filesProcessed">0</div>
722
+ <div class="stat-label">Файлов обработано</div>
723
+ </div>
724
+ <div class="stat-card">
725
+ <div class="stat-number" id="recordsProcessed">0</div>
726
+ <div class="stat-label">Записей обработано</div>
727
+ </div>
728
+ <div class="stat-card">
729
+ <div class="stat-number" id="errorsCount">0</div>
730
+ <div class="stat-label">Ошибок</div>
731
+ </div>
732
+ </div>
733
+
734
+ <h3 style="margin-top: 30px;">📋 Лог операций</h3>
735
+ <div id="karnetLog" class="log-container"></div>
736
+ </div>
737
+
738
+ <!-- Daily Accounting Tab -->
739
+ <div id="daily" class="tab-content">
740
+ <h2>📅 Ежедневный Учет</h2>
741
+
742
+ <div class="form-group">
743
+ <label for="dailyFolder">📁 Папка с файлами:</label>
744
+ <div style="display: flex; gap: 10px;">
745
+ <input type="text" id="dailyFolder" value="C:\\Work\\APP2\\Ежедневный">
746
+ <button onclick="browseDailyFolder()">📁 Обзор</button>
747
+ </div>
748
+ </div>
749
+
750
+ <div style="display: grid; grid-template-columns: 1fr auto 1fr; gap: 20px; margin-top: 20px;">
751
+ <div>
752
+ <h3>📄 Файлы и листы</h3>
753
+ <div id="filesTree" style="background: var(--sea-frame); padding: 15px; border-radius: 10px; height: 300px; overflow-y: auto;">
754
+ <!-- Files tree will be populated here -->
755
+ </div>
756
+ </div>
757
+
758
+ <div style="display: flex; flex-direction: column; justify-content: center; gap: 10px;">
759
+ <button onclick="moveSelectedSheet()">></button>
760
+ <button onclick="moveAllSheets()">>></button>
761
+ <button onclick="removeSelectedSheet()">&lt;</button>
762
+ <button onclick="clearSelectedSheets()">X</button>
763
+ </div>
764
+
765
+ <div>
766
+ <h3>📋 Выбранные листы</h3>
767
+ <div id="selectedTree" style="background: var(--sea-frame); padding: 15px; border-radius: 10px; height: 300px; overflow-y: auto;">
768
+ <!-- Selected sheets will be shown here -->
769
+ </div>
770
+ </div>
771
+ </div>
772
+
773
+ <div class="button-group" style="margin-top: 20px;">
774
+ <button onclick="transferSheets()">📦 Перенести</button>
775
+ <button class="success" onclick="mergeSheets()">🔗 Объединить</button>
776
+ <button class="secondary" onclick="refreshFiles()">🔄 Обновить</button>
777
+ </div>
778
+ </div>
779
+
780
+ <!-- Settings Tab -->
781
+ <div id="settings" class="tab-content">
782
+ <h2>⚙️ Настройки приложения</h2>
783
+
784
+ <div style="background: var(--sea-frame); padding: 20px; border-radius: 10px; margin-top: 20px;">
785
+ <h3>🌊 Karnet Manager Pro v3.0 - Морская версия</h3>
786
+
787
+ <div style="margin-top: 20px;">
788
+ <h4>✨ Новые возможности:</h4>
789
+ <ul style="margin-left: 20px; margin-top: 10px;">
790
+ <li>Морской интерфейс в спокойных тонах</li>
791
+ <li>Создание и управление шаблоном Книга5_fixed.xlsx</li>
792
+ <li>Быстрая обработка отдельных файлов карнетов</li>
793
+ <li>Улучшенная проверка соответствия заголовков</li>
794
+ <li>Детальная система логирования с эмодзи</li>
795
+ <li>Оптимизированный процесс объединения карнетов</li>
796
+ <li>Проверка отсутствующих заголовков в исходных файлах</li>
797
+ </ul>
798
+ </div>
799
+
800
+ <p style="margin-top: 20px; opacity: 0.8;">
801
+ 💾 Все настройки автоматически сохраняются в config.json
802
+ </p>
803
+ </div>
804
+
805
+ <div class="button-group" style="margin-top: 30px;">
806
+ <button onclick="saveSettings()">💾 Сохранить настройки</button>
807
+ <button class="warning" onclick="resetSettings()">🔄 Сбросить настройки</button>
808
+ </div>
809
+ </div>
810
+ </main>
811
+ </div>
812
+
813
+ <div class="status-bar">
814
+ <div class="status-message">
815
+ <span id="statusIcon">🌊</span>
816
+ <span id="statusText">Готов к работе</span>
817
+ </div>
818
+ <div class="progress-bar" id="progressBar" style="display: none;">
819
+ <div class="progress-fill"></div>
820
+ </div>
821
+ </div>
822
+
823
+ <div id="toast" class="toast"></div>
824
+
825
+ <div id="modal" class="modal">
826
+ <div class="modal-content">
827
+ <h3 id="modalTitle">Заголовок</h3>
828
+ <p id="modalMessage">Сообщение</p>
829
+ <button onclick="closeModal()" style="margin-top: 20px;">Закрыть</button>
830
+ </div>
831
+ </div>
832
+
833
+ <script>
834
+ // Global variables
835
+ let config = {
836
+ email: '',
837
+ emailHistory: [],
838
+ lastFolder: '',
839
+ targetFile: '',
840
+ templateFile: '',
841
+ writeIntoTarget: true
842
+ };
843
+
844
+ let stats = {
845
+ filesProcessed: 0,
846
+ recordsProcessed: 0,
847
+ errorsCount: 0
848
+ };
849
+
850
+ let quickFiles = [];
851
+ let selectedSheets = [];
852
+
853
+ // Initialize app
854
+ document.addEventListener('DOMContentLoaded', function() {
855
+ loadConfig();
856
+ initializeEventListeners();
857
+ updateStats();
858
+ logMessage('emailLog', '🌊 Приложение запущено и готово к работе', 'info');
859
+ logMessage('karnetLog', '🌊 Karnet Manager Pro v3.0 инициализирован', 'info');
860
+ });
861
+
862
+ function initializeEventListeners() {
863
+ // File input listeners
864
+ document.getElementById('quickFiles').addEventListener('change', handleQuickFilesSelect);
865
+
866
+ // Checkbox listeners
867
+ document.getElementById('headerPresent').addEventListener('change', function() {
868
+ if (this.checked) {
869
+ document.getElementById('headerAbsent').checked = false;
870
+ }
871
+ });
872
+
873
+ document.getElementById('headerAbsent').addEventListener('change', function() {
874
+ if (this.checked) {
875
+ document.getElementById('headerPresent').checked = false;
876
+ }
877
+ });
878
+
879
+ document.getElementById('quickToTarget').addEventListener('change', function() {
880
+ if (this.checked) {
881
+ document.getElementById('quickToNew').checked = false;
882
+ }
883
+ });
884
+
885
+ document.getElementById('quickToNew').addEventListener('change', function() {
886
+ if (this.checked) {
887
+ document.getElementById('quickToTarget').checked = false;
888
+ }
889
+ });
890
+ }
891
+
892
+ function switchTab(tabName) {
893
+ // Hide all tabs
894
+ document.querySelectorAll('.tab-content').forEach(tab => {
895
+ tab.classList.remove('active');
896
+ });
897
+
898
+ // Remove active class from all buttons
899
+ document.querySelectorAll('.tab-button').forEach(btn => {
900
+ btn.classList.remove('active');
901
+ });
902
+
903
+ // Show selected tab
904
+ document.getElementById(tabName).classList.add('active');
905
+
906
+ // Add active class to clicked button
907
+ event.target.classList.add('active');
908
+ }
909
+
910
+ function loadConfig() {
911
+ const savedConfig = localStorage.getItem('karnetConfig');
912
+ if (savedConfig) {
913
+ config = JSON.parse(savedConfig);
914
+ document.getElementById('email').value = config.email || '';
915
+ document.getElementById('karnetFolder').value = config.lastFolder || '';
916
+ document.getElementById('targetFile').value = config.targetFile || '';
917
+ }
918
+ }
919
+
920
+ function saveConfig() {
921
+ config.email = document.getElementById('email').value;
922
+ config.lastFolder = document.getElementById('karnetFolder').value;
923
+ config.targetFile = document.getElementById('targetFile').value;
924
+ localStorage.setItem('karnetConfig', JSON.stringify(config));
925
+ showToast('Настройки сохранены', 'success');
926
+ }
927
+
928
+ function logMessage(logId, message, level = 'info') {
929
+ const log = document.getElementById(logId);
930
+ const timestamp = new Date().toLocaleTimeString();
931
+ const entry = document.createElement('div');
932
+ entry.className = `log-entry ${level}`;
933
+
934
+ const icons = {
935
+ info: 'ℹ️',
936
+ success: '✅',
937
+ warning: '⚠️',
938
+ error: '❌'
939
+ };
940
+
941
+ entry.textContent = `[${timestamp}] ${icons[level] || 'ℹ️'} ${message}`;
942
+ log.appendChild(entry);
943
+ log.scrollTop = log.scrollHeight;
944
+ }
945
+
946
+ function updateStatus(message, level = 'info') {
947
+ const statusText = document.getElementById('statusText');
948
+ const statusIcon = document.getElementById('statusIcon');
949
+
950
+ const icons = {
951
+ info: '🌊',
952
+ success: '🐚',
953
+ warning: '⚓',
954
+ error: '🦈',
955
+ working: '🌀'
956
+ };
957
+
958
+ statusIcon.textContent = icons[level] || '🌊';
959
+ statusText.textContent = message;
960
+ }
961
+
962
+ function showProgress(show = true) {
963
+ document.getElementById('progressBar').style.display = show ? 'block' : 'none';
964
+ }
965
+
966
+ function showToast(message, type = 'info') {
967
+ const toast = document.getElementById('toast');
968
+ toast.textContent = message;
969
+ toast.className = `toast ${type} show`;
970
+
971
+ setTimeout(() => {
972
+ toast.classList.remove('show');
973
+ }, 3000);
974
+ }
975
+
976
+ function showModal(title, message) {
977
+ document.getElementById('modalTitle').textContent = title;
978
+ document.getElementById('modalMessage').textContent = message;
979
+ document.getElementById('modal').classList.add('active');
980
+ }
981
+
982
+ function closeModal() {
983
+ document.getElementById('modal').classList.remove('active');
984
+ }
985
+
986
+ function updateStats() {
987
+ document.getElementById('filesProcessed').textContent = stats.filesProcessed;
988
+ document.getElementById('recordsProcessed').textContent = stats.recordsProcessed;
989
+ document.getElementById('errorsCount').textContent = stats.errorsCount;
990
+ }
991
+
992
+ // Email Manager functions
993
+ function runOutlookSaver() {
994
+ updateStatus('Запуск OutlookAttachmentSaver...', 'working');
995
+ showProgress(true);
996
+ logMessage('emailLog', 'Запуск OutlookAttachmentSaver...', 'info');
997
+
998
+ // Simulate process
999
+ setTimeout(() => {
1000
+ logMessage('emailLog', 'OutlookAttachmentSaver успешно выполнен', 'success');
1001
+ updateStatus('OutlookAttachmentSaver выполнен', 'success');
1002
+ showProgress(false);
1003
+ showToast('OutlookAttachmentSaver выполнен успешно', 'success');
1004
+ }, 2000);
1005
+ }
1006
+
1007
+ function saveEmail() {
1008
+ const email = document.getElementById('email').value.trim();
1009
+ if (!email) {
1010
+ showToast('Введите email адрес', 'warning');
1011
+ return;
1012
+ }
1013
+
1014
+ if (!config.emailHistory.includes(email)) {
1015
+ config.emailHistory.push(email);
1016
+ }
1017
+ config.email = email;
1018
+ saveConfig();
1019
+
1020
+ logMessage('emailLog', `Email ${email} сохранен`, 'success');
1021
+ showToast('Email сохранен', 'success');
1022
+ }
1023
+
1024
+ // Karnet Manager functions
1025
+ function browseFolder() {
1026
+ // Simulate folder selection
1027
+ const folder = 'C:\\Work\\Karnets\\2024';
1028
+ document.getElementById('karnetFolder').value = folder;
1029
+ config.lastFolder = folder;
1030
+ saveConfig();
1031
+ logMessage('karnetLog', `Выбрана папка: ${folder}`, 'info');
1032
+ }
1033
+
1034
+ function browseTargetFile() {
1035
+ // Simulate file selection
1036
+ const file = 'C:\\Work\\Karnets\\Целевой файл.xlsm';
1037
+ document.getElementById('targetFile').value = file;
1038
+ config.targetFile = file;
1039
+ saveConfig();
1040
+ logMessage('karnetLog', `Выбран целевой файл: ${file}`, 'info');
1041
+ }
1042
+
1043
+ function checkTemplate() {
1044
+ updateStatus('Проверка шаблона...', 'working');
1045
+ showProgress(true);
1046
+ logMessage('karnetLog', '🔍 Проверка соответствия с мастер-шаблоном', 'info');
1047
+
1048
+ setTimeout(() => {
1049
+ logMessage('karnetLog', '📋 Ожидаемых заголовков в шаблоне: 25', 'info');
1050
+ logMessage('karnetLog', '📊 Обработано файлов: 12', 'info');
1051
+ logMessage('karnetLog', '✅ Все заголовки соответствуют шаблону!', 'success');
1052
+ updateStatus('Шаблон полностью соответствует', 'success');
1053
+ showProgress(false);
1054
+ showToast('Проверка шаблона завершена успешно', 'success');
1055
+ }, 3000);
1056
+ }
1057
+
1058
+ function createTemplate() {
1059
+ updateStatus('Создание шаблона...', 'working');
1060
+ showProgress(true);
1061
+ logMessage('karnetLog', '🛠️ Создание шаблона объединения карнетов...', 'info');
1062
+
1063
+ setTimeout(() => {
1064
+ logMessage('karnetLog', '🎉 Шаблон создан: Шаблоны/Шаблон_