GopalKrushnaMahapatra commited on
Commit
4043c92
Β·
verified Β·
1 Parent(s): c5a1ab8

Update ai-check.html

Browse files
Files changed (1) hide show
  1. ai-check.html +62 -93
ai-check.html CHANGED
@@ -228,8 +228,8 @@
228
  Ideal for anyone curious about AI detection or building their own detector interface.
229
  </p>
230
 
231
- <div class="grid md:grid-cols-3 gap-5 mt-3 text-xs">
232
- <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
233
  <div class="flex items-center gap-3 mb-2">
234
  <div class="w-9 h-9 rounded-full bg-sky-500/20 flex items-center justify-center">
235
  <span class="text-lg">πŸŽ“</span>
@@ -241,7 +241,7 @@
241
  </p>
242
  </div>
243
 
244
- <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
245
  <div class="flex items-center gap-3 mb-2">
246
  <div class="w-9 h-9 rounded-full bg-amber-500/20 flex items-center justify-center">
247
  <span class="text-lg">πŸ§‘β€πŸ«</span>
@@ -253,7 +253,7 @@
253
  </p>
254
  </div>
255
 
256
- <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
257
  <div class="flex items-center gap-3 mb-2">
258
  <div class="w-9 h-9 rounded-full bg-rose-500/20 flex items-center justify-center">
259
  <span class="text-lg">πŸ’»</span>
@@ -267,53 +267,6 @@
267
  </div>
268
  </section>
269
 
270
- <section class="mt-10 space-y-4">
271
- <h2 class="text-xl md:text-2xl font-semibold">How does this AI content checker work?</h2>
272
- <p class="text-sm text-slate-300">
273
- The scoring is intentionally simple, so you can read the JavaScript and fully understand it.
274
- </p>
275
-
276
- <div class="grid md:grid-cols-3 gap-5 mt-3 text-xs">
277
- <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
278
- <div class="flex items-center gap-3 mb-2">
279
- <div class="w-9 h-9 rounded-full bg-fuchsia-500/20 flex items-center justify-center">
280
- <span class="text-lg">1️⃣</span>
281
- </div>
282
- <p class="font-semibold text-sm">Tokenise the text</p>
283
- </div>
284
- <p>
285
- Text is lower-cased and split into words and sentences for basic statistics.
286
- </p>
287
- </div>
288
-
289
- <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
290
- <div class="flex items-center gap-3 mb-2">
291
- <div class="w-9 h-9 rounded-full bg-indigo-500/20 flex items-center justify-center">
292
- <span class="text-lg">2️⃣</span>
293
- </div>
294
- <p class="font-semibold text-sm">Measure patterns</p>
295
- </div>
296
- <p>
297
- It looks at vocabulary variety and average sentence length β€” long, repetitive text can
298
- look more AI-like.
299
- </p>
300
- </div>
301
-
302
- <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
303
- <div class="flex items-center gap-3 mb-2">
304
- <div class="w-9 h-9 rounded-full bg-emerald-500/20 flex items-center justify-center">
305
- <span class="text-lg">3️⃣</span>
306
- </div>
307
- <p class="font-semibold text-sm">Compute a score</p>
308
- </div>
309
- <p>
310
- Those metrics are combined into an AI-generated probability (0–100%), displayed and
311
- saved in your PDF report.
312
- </p>
313
- </div>
314
- </div>
315
- </section>
316
-
317
  <section class="mt-12">
318
  <h2 class="text-xl md:text-2xl font-semibold mb-3">Reviews for this AI checker</h2>
319
  <div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 md:p-6 relative overflow-hidden">
@@ -349,11 +302,10 @@
349
  window.location.href = "login.html";
350
  }
351
 
352
- // jsPDF helper
353
  function getJsPDF() {
354
  if (window.jspdf && window.jspdf.jsPDF) return window.jspdf.jsPDF;
355
  if (window.jsPDF) return window.jsPDF;
356
- alert("PDF library (jsPDF) did not load. Check your internet connection or CDN access.");
357
  return null;
358
  }
359
 
@@ -545,7 +497,8 @@
545
  word_count: wc,
546
  avg_sentence_length: avg,
547
  summary,
548
- text: textarea.value
 
549
  };
550
  } catch (err) {
551
  console.error(err);
@@ -556,55 +509,71 @@
556
  }
557
  };
558
 
559
- // PDF download
560
- downloadBtn.onclick = () => {
 
 
 
 
 
 
 
 
 
 
 
561
  if (!lastResult) {
562
  alert("Run at least one scan before downloading a report.");
563
  return;
564
  }
565
 
566
- const jsPDF = getJsPDF();
567
- if (!jsPDF) return;
568
-
569
- const doc = new jsPDF({ unit: "pt", format: "a4" });
570
-
571
- let y = 40;
572
- doc.setFontSize(16);
573
- doc.text("TrueWrite Scan β€” AI Content Report", 40, y); y += 22;
574
-
575
- doc.setFontSize(11);
576
- doc.text("Generated: " + new Date().toLocaleString(), 40, y); y += 18;
577
- doc.text("User: " + (user || "N/A"), 40, y); y += 18;
578
-
579
- doc.setFontSize(12);
580
- doc.text(`AI probability: ${lastResult.ai_percent}%`, 40, y); y += 16;
581
- doc.text(`Human probability: ${lastResult.human_percent}%`, 40, y); y += 16;
582
- doc.text(`Word count: ${lastResult.word_count}`, 40, y); y += 18;
 
 
 
 
583
 
584
- if (lastResult.avg_sentence_length !== null && lastResult.avg_sentence_length !== undefined) {
585
- doc.text(`Avg sentence length: ${lastResult.avg_sentence_length}`, 40, y); y += 18;
586
- }
 
587
 
588
- if (lastResult.summary) {
589
- doc.text("Summary:", 40, y); y += 16;
590
- doc.setFontSize(10);
591
- const lines = doc.splitTextToSize(lastResult.summary, 520);
592
- doc.text(lines, 40, y);
593
- y += lines.length * 12 + 10;
 
 
 
 
 
 
 
 
 
594
  }
595
-
596
- doc.setFontSize(11);
597
- doc.text("--- Original text (truncated) ---", 40, y); y += 18;
598
- const original = lastResult.text || "";
599
- const truncated = original.length > 4000 ? original.slice(0, 4000) + "\n\n[TRUNCATED]" : original;
600
- const textLines = doc.splitTextToSize(truncated, 520);
601
- doc.setFontSize(10);
602
- doc.text(textLines, 40, y);
603
-
604
- doc.save("truewrite-ai-report.pdf");
605
  };
606
 
607
- // Reviews slider
 
608
  const reviews = [
609
  {
610
  name: "Aarav S.",
 
228
  Ideal for anyone curious about AI detection or building their own detector interface.
229
  </p>
230
 
231
+ <div class="grid md:grid-cols-3 gap-5 mt-3">
232
+ <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4 text-xs">
233
  <div class="flex items-center gap-3 mb-2">
234
  <div class="w-9 h-9 rounded-full bg-sky-500/20 flex items-center justify-center">
235
  <span class="text-lg">πŸŽ“</span>
 
241
  </p>
242
  </div>
243
 
244
+ <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4 text-xs">
245
  <div class="flex items-center gap-3 mb-2">
246
  <div class="w-9 h-9 rounded-full bg-amber-500/20 flex items-center justify-center">
247
  <span class="text-lg">πŸ§‘β€πŸ«</span>
 
253
  </p>
254
  </div>
255
 
256
+ <div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4 text-xs">
257
  <div class="flex items-center gap-3 mb-2">
258
  <div class="w-9 h-9 rounded-full bg-rose-500/20 flex items-center justify-center">
259
  <span class="text-lg">πŸ’»</span>
 
267
  </div>
268
  </section>
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  <section class="mt-12">
271
  <h2 class="text-xl md:text-2xl font-semibold mb-3">Reviews for this AI checker</h2>
272
  <div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 md:p-6 relative overflow-hidden">
 
302
  window.location.href = "login.html";
303
  }
304
 
305
+ // jsPDF helper (kept for backwards compatibility β€” not used for server PDF)
306
  function getJsPDF() {
307
  if (window.jspdf && window.jspdf.jsPDF) return window.jspdf.jsPDF;
308
  if (window.jsPDF) return window.jsPDF;
 
309
  return null;
310
  }
311
 
 
497
  word_count: wc,
498
  avg_sentence_length: avg,
499
  summary,
500
+ text: textarea.value,
501
+ file: file || null
502
  };
503
  } catch (err) {
504
  console.error(err);
 
509
  }
510
  };
511
 
512
+ // Helper to parse filename from Content-Disposition
513
+ function filenameFromContentDisposition(header) {
514
+ if (!header) return null;
515
+ // Try utf-8 filename* then filename
516
+ const fnStar = header.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
517
+ if (fnStar && fnStar[1]) return decodeURIComponent(fnStar[1].replace(/["']/g, ''));
518
+ const fn = header.match(/filename\s*=\s*["']?([^;"']+)["']?/i);
519
+ if (fn && fn[1]) return fn[1].replace(/["']/g, '');
520
+ return null;
521
+ }
522
+
523
+ // Download PDF (calls backend /report/ai or /report/ai-file)
524
+ downloadBtn.onclick = async () => {
525
  if (!lastResult) {
526
  alert("Run at least one scan before downloading a report.");
527
  return;
528
  }
529
 
530
+ const file = lastResult.file;
531
+ try {
532
+ let res;
533
+ if (file && !(file.type === "text/plain" || file.name.toLowerCase().endsWith(".txt"))) {
534
+ // POST file to /report/ai-file
535
+ const form = new FormData();
536
+ form.append("file", file, file.name);
537
+ res = await fetch(`${BACKEND_URL}/report/ai-file`, {
538
+ method: "POST",
539
+ headers: { "Authorization": `Bearer ${token}` },
540
+ body: form
541
+ });
542
+ } else {
543
+ // Use GET with text param (URL-encode)
544
+ const txt = lastResult.text || "";
545
+ const q = encodeURIComponent(txt);
546
+ res = await fetch(`${BACKEND_URL}/report/ai?text=${q}`, {
547
+ method: "GET",
548
+ headers: { "Authorization": `Bearer ${token}` }
549
+ });
550
+ }
551
 
552
+ if (!res.ok) {
553
+ const text = await res.text();
554
+ throw new Error(text || `Server error: ${res.status}`);
555
+ }
556
 
557
+ const blob = await res.blob();
558
+ const cd = res.headers.get('content-disposition');
559
+ const fname = filenameFromContentDisposition(cd) || "TrueWrite_AiReport.pdf";
560
+
561
+ const url = URL.createObjectURL(blob);
562
+ const a = document.createElement('a');
563
+ a.href = url;
564
+ a.download = fname;
565
+ document.body.appendChild(a);
566
+ a.click();
567
+ a.remove();
568
+ URL.revokeObjectURL(url);
569
+ } catch (err) {
570
+ console.error(err);
571
+ alert("Failed to download report: " + (err.message || err));
572
  }
 
 
 
 
 
 
 
 
 
 
573
  };
574
 
575
+ // Reviews slider and other UI (unchanged) ...
576
+ // (kept exactly as you provided)
577
  const reviews = [
578
  {
579
  name: "Aarav S.",