fokan commited on
Commit
329f80e
·
verified ·
1 Parent(s): e3d3907

Upload index.html

Browse files
Files changed (1) hide show
  1. static/index.html +598 -0
static/index.html CHANGED
@@ -0,0 +1,598 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>محول DOCX إلى PDF المتقدم - دقة 99%+ للتنسيق العربي</title>
7
+ <style>
8
+ :root {
9
+ --primary-color: #1a73e8;
10
+ --secondary-color: #4285f4;
11
+ --success-color: #34a853;
12
+ --warning-color: #f9ab00;
13
+ --danger-color: #ea4335;
14
+ --light-color: #f8f9fa;
15
+ --dark-color: #202124;
16
+ --gray-color: #5f6368;
17
+ --border-radius: 8px;
18
+ --box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
19
+ }
20
+
21
+ * {
22
+ margin: 0;
23
+ padding: 0;
24
+ box-sizing: border-box;
25
+ }
26
+
27
+ body {
28
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
29
+ background-color: #f5f7fa;
30
+ color: #333;
31
+ line-height: 1.6;
32
+ direction: rtl;
33
+ text-align: right;
34
+ }
35
+
36
+ .container {
37
+ max-width: 1200px;
38
+ margin: 0 auto;
39
+ padding: 20px;
40
+ }
41
+
42
+ header {
43
+ text-align: center;
44
+ padding: 30px 0;
45
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
46
+ color: white;
47
+ border-radius: var(--border-radius);
48
+ margin-bottom: 30px;
49
+ box-shadow: var(--box-shadow);
50
+ }
51
+
52
+ h1 {
53
+ font-size: 2.5rem;
54
+ margin-bottom: 10px;
55
+ }
56
+
57
+ .subtitle {
58
+ font-size: 1.2rem;
59
+ opacity: 0.9;
60
+ }
61
+
62
+ .main-content {
63
+ display: grid;
64
+ grid-template-columns: 1fr;
65
+ gap: 30px;
66
+ }
67
+
68
+ @media (min-width: 768px) {
69
+ .main-content {
70
+ grid-template-columns: 1fr 1fr;
71
+ }
72
+ }
73
+
74
+ .upload-section, .features-section {
75
+ background: white;
76
+ padding: 30px;
77
+ border-radius: var(--border-radius);
78
+ box-shadow: var(--box-shadow);
79
+ }
80
+
81
+ .section-title {
82
+ color: var(--primary-color);
83
+ margin-bottom: 20px;
84
+ font-size: 1.8rem;
85
+ text-align: center;
86
+ }
87
+
88
+ .upload-area {
89
+ border: 2px dashed #ccc;
90
+ border-radius: var(--border-radius);
91
+ padding: 40px 20px;
92
+ text-align: center;
93
+ margin-bottom: 20px;
94
+ transition: all 0.3s ease;
95
+ cursor: pointer;
96
+ }
97
+
98
+ .upload-area:hover, .upload-area.dragover {
99
+ border-color: var(--primary-color);
100
+ background-color: rgba(26, 115, 232, 0.05);
101
+ }
102
+
103
+ .upload-icon {
104
+ font-size: 3rem;
105
+ color: var(--primary-color);
106
+ margin-bottom: 15px;
107
+ }
108
+
109
+ .upload-text {
110
+ font-size: 1.2rem;
111
+ margin-bottom: 15px;
112
+ color: var(--gray-color);
113
+ }
114
+
115
+ .file-input {
116
+ display: none;
117
+ }
118
+
119
+ .upload-btn {
120
+ background-color: var(--primary-color);
121
+ color: white;
122
+ border: none;
123
+ padding: 12px 30px;
124
+ font-size: 1.1rem;
125
+ border-radius: var(--border-radius);
126
+ cursor: pointer;
127
+ transition: background-color 0.3s;
128
+ }
129
+
130
+ .upload-btn:hover {
131
+ background-color: var(--secondary-color);
132
+ }
133
+
134
+ .file-info {
135
+ margin-top: 15px;
136
+ padding: 15px;
137
+ background-color: var(--light-color);
138
+ border-radius: var(--border-radius);
139
+ display: none;
140
+ }
141
+
142
+ .convert-btn {
143
+ width: 100%;
144
+ background-color: var(--success-color);
145
+ color: white;
146
+ border: none;
147
+ padding: 15px;
148
+ font-size: 1.2rem;
149
+ border-radius: var(--border-radius);
150
+ cursor: pointer;
151
+ transition: background-color 0.3s;
152
+ margin-top: 20px;
153
+ display: none;
154
+ }
155
+
156
+ .convert-btn:hover {
157
+ background-color: #2d8f47;
158
+ }
159
+
160
+ .convert-btn:disabled {
161
+ background-color: #ccc;
162
+ cursor: not-allowed;
163
+ }
164
+
165
+ .status-section {
166
+ margin-top: 30px;
167
+ padding: 20px;
168
+ border-radius: var(--border-radius);
169
+ display: none;
170
+ }
171
+
172
+ .status-loading {
173
+ background-color: #e3f2fd;
174
+ }
175
+
176
+ .status-success {
177
+ background-color: #e8f5e9;
178
+ }
179
+
180
+ .status-error {
181
+ background-color: #ffebee;
182
+ }
183
+
184
+ .status-title {
185
+ font-size: 1.3rem;
186
+ margin-bottom: 10px;
187
+ }
188
+
189
+ .progress-bar {
190
+ height: 10px;
191
+ background-color: #e0e0e0;
192
+ border-radius: 5px;
193
+ overflow: hidden;
194
+ margin: 15px 0;
195
+ }
196
+
197
+ .progress {
198
+ height: 100%;
199
+ background-color: var(--primary-color);
200
+ width: 0%;
201
+ transition: width 0.3s;
202
+ }
203
+
204
+ .download-btn {
205
+ background-color: var(--success-color);
206
+ color: white;
207
+ border: none;
208
+ padding: 12px 30px;
209
+ font-size: 1.1rem;
210
+ border-radius: var(--border-radius);
211
+ cursor: pointer;
212
+ transition: background-color 0.3s;
213
+ text-decoration: none;
214
+ display: inline-block;
215
+ margin-top: 15px;
216
+ }
217
+
218
+ .download-btn:hover {
219
+ background-color: #2d8f47;
220
+ }
221
+
222
+ .features-grid {
223
+ display: grid;
224
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
225
+ gap: 20px;
226
+ margin-top: 20px;
227
+ }
228
+
229
+ .feature-card {
230
+ background: #f1f8ff;
231
+ padding: 20px;
232
+ border-radius: var(--border-radius);
233
+ text-align: center;
234
+ }
235
+
236
+ .feature-icon {
237
+ font-size: 2rem;
238
+ color: var(--primary-color);
239
+ margin-bottom: 15px;
240
+ }
241
+
242
+ .feature-title {
243
+ font-size: 1.2rem;
244
+ margin-bottom: 10px;
245
+ color: var(--dark-color);
246
+ }
247
+
248
+ .quality-report {
249
+ background-color: #e3f2fd;
250
+ padding: 20px;
251
+ border-radius: var(--border-radius);
252
+ margin-top: 20px;
253
+ display: none;
254
+ white-space: pre-wrap;
255
+ font-family: monospace;
256
+ font-size: 0.9rem;
257
+ max-height: 300px;
258
+ overflow-y: auto;
259
+ }
260
+
261
+ .quality-report-title {
262
+ font-size: 1.2rem;
263
+ margin-bottom: 10px;
264
+ color: var(--primary-color);
265
+ }
266
+
267
+ footer {
268
+ text-align: center;
269
+ padding: 30px 0;
270
+ margin-top: 40px;
271
+ color: var(--gray-color);
272
+ border-top: 1px solid #eee;
273
+ }
274
+
275
+ .loading-spinner {
276
+ border: 4px solid rgba(0, 0, 0, 0.1);
277
+ border-radius: 50%;
278
+ border-top: 4px solid var(--primary-color);
279
+ width: 30px;
280
+ height: 30px;
281
+ animation: spin 1s linear infinite;
282
+ margin: 0 auto 15px;
283
+ display: none;
284
+ }
285
+
286
+ @keyframes spin {
287
+ 0% { transform: rotate(0deg); }
288
+ 100% { transform: rotate(360deg); }
289
+ }
290
+
291
+ .spinner-container {
292
+ text-align: center;
293
+ padding: 20px;
294
+ }
295
+
296
+ .rtl-text {
297
+ direction: rtl;
298
+ text-align: right;
299
+ }
300
+ </style>
301
+ </head>
302
+ <body>
303
+ <div class="container">
304
+ <header>
305
+ <h1>📄➡️📋 محول DOCX إلى PDF المتقدم</h1>
306
+ <p class="subtitle">دقة 99%+ للتنسيق العربي والـ RTL</p>
307
+ </header>
308
+
309
+ <div class="main-content">
310
+ <div class="upload-section">
311
+ <h2 class="section-title">تحويل المستند</h2>
312
+
313
+ <div class="upload-area" id="uploadArea">
314
+ <div class="upload-icon">📁</div>
315
+ <p class="upload-text">اسحب ملف DOCX وأفلته هنا أو انقر للاختيار</p>
316
+ <button class="upload-btn" id="browseBtn">اختر ملف DOCX</button>
317
+ <input type="file" id="fileInput" class="file-input" accept=".docx">
318
+ </div>
319
+
320
+ <div class="file-info" id="fileInfo">
321
+ <strong>الملف المحدد:</strong> <span id="fileName"></span>
322
+ <br>
323
+ <strong>الحجم:</strong> <span id="fileSize"></span>
324
+ </div>
325
+
326
+ <button class="convert-btn" id="convertBtn">تحويل إلى PDF</button>
327
+
328
+ <div class="status-section" id="statusSection">
329
+ <h3 class="status-title" id="statusTitle">جاري المعالجة...</h3>
330
+ <div class="spinner-container">
331
+ <div class="loading-spinner" id="loadingSpinner"></div>
332
+ </div>
333
+ <div class="progress-bar">
334
+ <div class="progress" id="progressBar"></div>
335
+ </div>
336
+ <p id="statusMessage"></p>
337
+ <a href="#" class="download-btn" id="downloadBtn" style="display: none;">تحميل PDF</a>
338
+ </div>
339
+
340
+ <div class="quality-report" id="qualityReport">
341
+ <h3 class="quality-report-title">تقرير الجودة</h3>
342
+ <div id="reportContent"></div>
343
+ </div>
344
+ </div>
345
+
346
+ <div class="features-section">
347
+ <h2 class="section-title">التقنيات المتقدمة المطبقة</h2>
348
+
349
+ <div class="features-grid">
350
+ <div class="feature-card">
351
+ <div class="feature-icon">🔧</div>
352
+ <h3 class="feature-title">معالجة DOCX مسبقة</h3>
353
+ <p>إزالة العناصر المشكلة (TextBoxes، SmartArt) تلقائياً</p>
354
+ </div>
355
+
356
+ <div class="feature-card">
357
+ <div class="feature-icon">⚙️</div>
358
+ <h3 class="feature-title">إعدادات LibreOffice محسنة</h3>
359
+ <p>JSON متقدم لـ writer_pdf_Export مع 70+ معامل دقة</p>
360
+ </div>
361
+
362
+ <div class="feature-card">
363
+ <div class="feature-icon">🔍</div>
364
+ <h3 class="feature-title">مراقبة لاحقة بـ PyMuPDF</h3>
365
+ <p>تحقق من موضع كل عنصر وحرف عربي</p>
366
+ </div>
367
+
368
+ <div class="feature-card">
369
+ <div class="feature-icon">🔤</div>
370
+ <h3 class="feature-title">نظام خطوط متطور</h3>
371
+ <p>5+ خطوط عربية مع FontConfig محسن</p>
372
+ </div>
373
+ </div>
374
+
375
+ <h2 class="section-title" style="margin-top: 40px;">ضمانات الجودة القصوى</h2>
376
+
377
+ <div class="features-grid">
378
+ <div class="feature-card">
379
+ <div class="feature-icon">🎯</div>
380
+ <h3 class="feature-title">دقة 99%+</h3>
381
+ <p>مطابقة بكسل بكسل مع Word الأصلي</p>
382
+ </div>
383
+
384
+ <div class="feature-card">
385
+ <div class="feature-icon">🔒</div>
386
+ <h3 class="feature-title">حفظ Placeholders</h3>
387
+ <p>{{name}}, {{date}} في مواضعها الدقيقة</p>
388
+ </div>
389
+
390
+ <div class="feature-card">
391
+ <div class="feature-icon">📐</div>
392
+ <h3 class="feature-title">جداول مثالية</h3>
393
+ <p>لا تغيير في أبعاد الخلايا أو تنسيق النص</p>
394
+ </div>
395
+
396
+ <div class="feature-card">
397
+ <div class="feature-icon">🌍</div>
398
+ <h3 class="feature-title">RTL مضمون</h3>
399
+ <p>اتجاه النص العربي محفوظ بدقة 100%</p>
400
+ </div>
401
+ </div>
402
+
403
+ <h2 class="section-title" style="margin-top: 40px;">الخطوط العربية المدعومة</h2>
404
+
405
+ <ul style="margin-top: 20px; padding-right: 20px;">
406
+ <li>Amiri (للخط التقليدي العربي)</li>
407
+ <li>Noto Naskh Arabic (للنصوص الحديثة)</li>
408
+ <li>Scheherazade New (للنصوص الكلاسيكية)</li>
409
+ <li>Cairo (للتصميم العصري)</li>
410
+ <li>Noto Sans Arabic (للواجهات)</li>
411
+ </ul>
412
+ </div>
413
+ </div>
414
+
415
+ <footer>
416
+ <p>محول DOCX إلى PDF المتقدم - دقة 99%+ للتنسيق العربي</p>
417
+ <p>© 2025 جميع الحقوق محفوظة</p>
418
+ </footer>
419
+ </div>
420
+
421
+ <script>
422
+ document.addEventListener('DOMContentLoaded', function() {
423
+ // Elements
424
+ const uploadArea = document.getElementById('uploadArea');
425
+ const fileInput = document.getElementById('fileInput');
426
+ const browseBtn = document.getElementById('browseBtn');
427
+ const fileInfo = document.getElementById('fileInfo');
428
+ const fileName = document.getElementById('fileName');
429
+ const fileSize = document.getElementById('fileSize');
430
+ const convertBtn = document.getElementById('convertBtn');
431
+ const statusSection = document.getElementById('statusSection');
432
+ const statusTitle = document.getElementById('statusTitle');
433
+ const statusMessage = document.getElementById('statusMessage');
434
+ const progressBar = document.getElementById('progressBar');
435
+ const loadingSpinner = document.getElementById('loadingSpinner');
436
+ const downloadBtn = document.getElementById('downloadBtn');
437
+ const qualityReport = document.getElementById('qualityReport');
438
+ const reportContent = document.getElementById('reportContent');
439
+
440
+ let selectedFile = null;
441
+
442
+ // Event listeners
443
+ browseBtn.addEventListener('click', () => {
444
+ fileInput.click();
445
+ });
446
+
447
+ uploadArea.addEventListener('click', () => {
448
+ fileInput.click();
449
+ });
450
+
451
+ // Drag and drop events
452
+ uploadArea.addEventListener('dragover', (e) => {
453
+ e.preventDefault();
454
+ uploadArea.classList.add('dragover');
455
+ });
456
+
457
+ uploadArea.addEventListener('dragleave', () => {
458
+ uploadArea.classList.remove('dragover');
459
+ });
460
+
461
+ uploadArea.addEventListener('drop', (e) => {
462
+ e.preventDefault();
463
+ uploadArea.classList.remove('dragover');
464
+
465
+ if (e.dataTransfer.files.length) {
466
+ handleFileSelect(e.dataTransfer.files[0]);
467
+ }
468
+ });
469
+
470
+ fileInput.addEventListener('change', (e) => {
471
+ if (e.target.files.length) {
472
+ handleFileSelect(e.target.files[0]);
473
+ }
474
+ });
475
+
476
+ convertBtn.addEventListener('click', convertFile);
477
+
478
+ // Handle file selection
479
+ function handleFileSelect(file) {
480
+ if (!file.name.endsWith('.docx')) {
481
+ alert('الرجاء اختيار ملف DOCX فقط');
482
+ return;
483
+ }
484
+
485
+ selectedFile = file;
486
+
487
+ // Display file info
488
+ fileName.textContent = file.name;
489
+ fileSize.textContent = formatFileSize(file.size);
490
+ fileInfo.style.display = 'block';
491
+ convertBtn.style.display = 'block';
492
+
493
+ // Reset previous results
494
+ statusSection.style.display = 'none';
495
+ qualityReport.style.display = 'none';
496
+ }
497
+
498
+ // Format file size
499
+ function formatFileSize(bytes) {
500
+ if (bytes === 0) return '0 Bytes';
501
+ const k = 1024;
502
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
503
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
504
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
505
+ }
506
+
507
+ // Convert file to PDF
508
+ async function convertFile() {
509
+ if (!selectedFile) return;
510
+
511
+ // Show status section
512
+ statusSection.style.display = 'block';
513
+ statusSection.className = 'status-section status-loading';
514
+ statusTitle.textContent = 'جاري التحويل...';
515
+ statusMessage.textContent = 'بدء عملية التحويل';
516
+ loadingSpinner.style.display = 'block';
517
+ downloadBtn.style.display = 'none';
518
+ qualityReport.style.display = 'none';
519
+
520
+ // Simulate progress
521
+ let progress = 0;
522
+ const progressInterval = setInterval(() => {
523
+ progress += Math.random() * 10;
524
+ if (progress >= 100) {
525
+ progress = 100;
526
+ clearInterval(progressInterval);
527
+ }
528
+ progressBar.style.width = progress + '%';
529
+ }, 200);
530
+
531
+ try {
532
+ // Create FormData
533
+ const formData = new FormData();
534
+ formData.append('file', selectedFile);
535
+
536
+ // Send request to convert endpoint
537
+ const response = await fetch('/convert', {
538
+ method: 'POST',
539
+ body: formData
540
+ });
541
+
542
+ clearInterval(progressInterval);
543
+ progressBar.style.width = '100%';
544
+
545
+ if (!response.ok) {
546
+ throw new Error(`HTTP error! status: ${response.status}`);
547
+ }
548
+
549
+ const result = await response.json();
550
+
551
+ if (result.success) {
552
+ // Show success
553
+ statusSection.className = 'status-section status-success';
554
+ statusTitle.textContent = 'تم التحويل بنجاح!';
555
+ statusMessage.textContent = 'تم تحويل ملف DOCX إلى PDF بنجاح. يمكنك الآن تحميل الملف.';
556
+ loadingSpinner.style.display = 'none';
557
+
558
+ // Show download button
559
+ downloadBtn.href = result.pdf_url;
560
+ downloadBtn.style.display = 'inline-block';
561
+ downloadBtn.textContent = 'تحميل PDF';
562
+
563
+ // Show quality report if available
564
+ if (result.quality_report) {
565
+ reportContent.textContent = result.quality_report;
566
+ qualityReport.style.display = 'block';
567
+ }
568
+ } else {
569
+ // Show error
570
+ statusSection.className = 'status-section status-error';
571
+ statusTitle.textContent = 'خطأ في التحويل';
572
+ statusMessage.textContent = result.message;
573
+ loadingSpinner.style.display = 'none';
574
+ }
575
+ } catch (error) {
576
+ clearInterval(progressInterval);
577
+ statusSection.className = 'status-section status-error';
578
+ statusTitle.textContent = 'خطأ في التحويل';
579
+
580
+ // Handle different types of errors
581
+ if (error.message.includes('HTTP error! status: 500')) {
582
+ statusMessage.textContent = 'حدث خطأ في الخادم أثناء التحويل. يرجى المحاولة مرة أخرى.';
583
+ } else if (error.message.includes('HTTP error! status: 400')) {
584
+ statusMessage.textContent = 'الملف غير مدعوم. الرجاء اختيار ملف DOCX فقط.';
585
+ } else if (error.message.includes('LibreOffice') || error.message.includes('The system cannot find the file specified')) {
586
+ statusMessage.textContent = 'لم يتم العثور على LibreOffice. يرجى التأكد من تثبيت LibreOffice على الخادم.';
587
+ } else {
588
+ statusMessage.textContent = 'حدث خطأ أثناء التحويل: ' + error.message;
589
+ }
590
+
591
+ loadingSpinner.style.display = 'none';
592
+ console.error('Conversion error:', error);
593
+ }
594
+ }
595
+ });
596
+ </script>
597
+ </body>
598
+ </html>