ministerchief commited on
Commit
490180e
·
verified ·
1 Parent(s): 8f42448

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +0 -235
templates/index.html CHANGED
@@ -119,240 +119,5 @@
119
  </div>
120
  </div>
121
  </div>
122
-
123
- <!-- ── Scripts ────────────────────────────────────────────── -->
124
- <script>
125
- /* ──────────────────────────── Three.js 3D PDF icon ──── */
126
- (function () {
127
- const container = document.getElementById('three-header');
128
- const W = 120, H = 120;
129
-
130
- const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
131
- renderer.setPixelRatio(window.devicePixelRatio);
132
- renderer.setSize(W, H);
133
- container.appendChild(renderer.domElement);
134
-
135
- const scene = new THREE.Scene();
136
- const camera = new THREE.PerspectiveCamera(38, W / H, 0.1, 100);
137
- camera.position.set(0, 0, 5);
138
-
139
- scene.add(new THREE.AmbientLight(0xffffff, 0.6));
140
- const dirLight = new THREE.DirectionalLight(0xffffff, 0.9);
141
- dirLight.position.set(4, 6, 4);
142
- scene.add(dirLight);
143
-
144
- const bodyGeo = new THREE.BoxGeometry(1.4, 1.8, 0.12);
145
- const bodyMat = new THREE.MeshStandardMaterial({ color: 0xffffff });
146
- const body = new THREE.Mesh(bodyGeo, bodyMat);
147
- scene.add(body);
148
-
149
- const cornerShape = new THREE.Shape();
150
- cornerShape.moveTo(0, 0);
151
- cornerShape.lineTo(0.38, 0);
152
- cornerShape.lineTo(0, -0.38);
153
- cornerShape.closePath();
154
-
155
- const cornerGeo = new THREE.ExtrudeGeometry(cornerShape, { depth: 0.13, bevelEnabled: false });
156
- const cornerMat = new THREE.MeshStandardMaterial({ color: 0x5048c8 });
157
- const corner = new THREE.Mesh(cornerGeo, cornerMat);
158
- corner.position.set(0.7, 0.9, 0);
159
- scene.add(corner);
160
-
161
- const stripeGeo = new THREE.BoxGeometry(0.9, 0.06, 0.14);
162
- const stripeMat = new THREE.MeshStandardMaterial({ color: 0xe24b4a });
163
-
164
- [-0.2, 0.1, 0.4].forEach(y => {
165
- const s = new THREE.Mesh(stripeGeo, stripeMat);
166
- s.position.set(-0.12, y, 0);
167
- scene.add(s);
168
- });
169
-
170
- const planeGeo = new THREE.PlaneGeometry(1.45, 1.85);
171
- const planeMat = new THREE.MeshStandardMaterial({ color: 0x5048c8 });
172
- const plane = new THREE.Mesh(planeGeo, planeMat);
173
- plane.position.set(0.10, -0.10, -0.20);
174
- scene.add(plane);
175
-
176
- function animate() {
177
- requestAnimationFrame(animate);
178
- body.rotation.y += 0.012;
179
- corner.rotation.y = body.rotation.y;
180
- plane.rotation.y = body.rotation.y;
181
- scene.children.forEach(c => { if (c.isMesh) c.rotation.y = body.rotation.y; });
182
- renderer.render(scene, camera);
183
- }
184
- animate();
185
- })();
186
-
187
- /* ──────────────────────────── App state ───────────────── */
188
- const FREE_LIMIT = 15;
189
- let selectedFiles = [];
190
-
191
- const dropZone = document.getElementById('drop-zone');
192
- const fileInput = document.getElementById('file-input');
193
- const previewGrid = document.getElementById('preview-grid');
194
- const counterBar = document.getElementById('counter-bar');
195
- const countNum = document.getElementById('count-num');
196
- const countDot = document.getElementById('count-dot');
197
- const countLimit = document.getElementById('count-limit-text');
198
- const convertBtn = document.getElementById('convert-btn');
199
- const btnLabel = document.getElementById('btn-label');
200
- const loadingBar = document.getElementById('loading-bar');
201
- const clearBtn = document.getElementById('clear-btn');
202
- const overlay = document.getElementById('overlay');
203
-
204
- /* drag & drop */
205
- dropZone.addEventListener('dragover', e => {
206
- e.preventDefault();
207
- dropZone.classList.add('drag-over');
208
- });
209
-
210
- dropZone.addEventListener('dragleave', () => dropZone.classList.remove('drag-over'));
211
-
212
- dropZone.addEventListener('drop', e => {
213
- e.preventDefault();
214
- dropZone.classList.remove('drag-over');
215
- addFiles(e.dataTransfer.files);
216
- });
217
-
218
- fileInput.addEventListener('change', () => {
219
- addFiles(fileInput.files);
220
- fileInput.value = '';
221
- });
222
-
223
- function addFiles(fileList) {
224
- const incoming = Array.from(fileList).filter(f => f.type.startsWith('image/'));
225
- const newTotal = selectedFiles.length + incoming.length;
226
-
227
- if (newTotal > FREE_LIMIT) {
228
- const allowed = incoming.slice(0, FREE_LIMIT - selectedFiles.length);
229
- allowed.forEach(pushFile);
230
- updateUI();
231
- showPremiumDialog();
232
- return;
233
- }
234
-
235
- incoming.forEach(pushFile);
236
- updateUI();
237
- }
238
-
239
- function pushFile(file) {
240
- const url = URL.createObjectURL(file);
241
- selectedFiles.push({ file, url });
242
- }
243
-
244
- function removeFile(index) {
245
- URL.revokeObjectURL(selectedFiles[index].url);
246
- selectedFiles.splice(index, 1);
247
- updateUI();
248
- }
249
-
250
- function clearAll() {
251
- selectedFiles.forEach(f => URL.revokeObjectURL(f.url));
252
- selectedFiles = [];
253
- updateUI();
254
- }
255
-
256
- function updateUI() {
257
- const n = selectedFiles.length;
258
-
259
- if (n > 0) {
260
- counterBar.classList.add('visible');
261
- countNum.textContent = n;
262
- countLimit.textContent = `${n} / ${FREE_LIMIT} free slots used`;
263
- } else {
264
- counterBar.classList.remove('visible');
265
- }
266
-
267
- previewGrid.innerHTML = '';
268
-
269
- selectedFiles.forEach(({ url }, i) => {
270
- const item = document.createElement('div');
271
- item.className = 'preview-item';
272
- item.innerHTML = `
273
- <img src="${url}" />
274
- <span class="order-badge">${i + 1}</span>
275
- <button class="remove-btn" onclick="removeFile(${i})">✕</button>
276
- `;
277
- previewGrid.appendChild(item);
278
- });
279
-
280
- convertBtn.disabled = n === 0;
281
- clearBtn.style.display = n > 0 ? 'block' : 'none';
282
- }
283
-
284
- /* ──────────────────────────── FIXED CONVERT FUNCTION ───────────────── */
285
- async function convertToPDF() {
286
- if (selectedFiles.length === 0) return;
287
-
288
- if (selectedFiles.length > FREE_LIMIT) {
289
- showPremiumDialog();
290
- return;
291
- }
292
-
293
- setLoading(true);
294
-
295
- const formData = new FormData();
296
- selectedFiles.forEach(({ file }) => {
297
- formData.append('images', file);
298
- });
299
-
300
- try {
301
- // ✅ FIXED LINE (IMPORTANT)
302
- const res = await fetch('/convert', {
303
- method: 'POST',
304
- body: formData
305
- });
306
-
307
- if (!res.ok) {
308
- const json = await res.json().catch(() => ({}));
309
-
310
- if (json.error === 'limit_exceeded') {
311
- showPremiumDialog();
312
- } else {
313
- showToast(json.error || 'Conversion failed');
314
- }
315
- return;
316
- }
317
-
318
- const blob = await res.blob();
319
- const link = document.createElement('a');
320
- link.href = URL.createObjectURL(blob);
321
- link.download = 'converted.pdf';
322
- link.click();
323
-
324
- showToast('PDF downloaded successfully!');
325
- } catch (err) {
326
- showToast('Server not running. Run python app.py');
327
- } finally {
328
- setLoading(false);
329
- }
330
- }
331
-
332
- function setLoading(on) {
333
- convertBtn.disabled = on;
334
- btnLabel.style.display = on ? 'none' : 'inline';
335
- loadingBar.style.display = on ? 'block' : 'none';
336
- }
337
-
338
- /* ──────────────────────────── Premium dialog ───────────────── */
339
- function showPremiumDialog() {
340
- overlay.classList.add('show');
341
- }
342
-
343
- function closeDialog(e) {
344
- if (!e || e.target === overlay) {
345
- overlay.classList.remove('show');
346
- }
347
- }
348
-
349
- /* ──────────────────────────── Toast ───────────────── */
350
- function showToast(msg) {
351
- const t = document.getElementById('toast');
352
- t.textContent = msg;
353
- t.classList.add('show');
354
- setTimeout(() => t.classList.remove('show'), 3000);
355
- }
356
- </script>
357
  </body>
358
  </html>
 
119
  </div>
120
  </div>
121
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  </body>
123
  </html>