GopalKrushnaMahapatra commited on
Commit
8e5835b
·
verified ·
1 Parent(s): f538f80

Update ai-check.html

Browse files
Files changed (1) hide show
  1. ai-check.html +77 -127
ai-check.html CHANGED
@@ -6,7 +6,7 @@
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
  <script src="https://cdn.tailwindcss.com"></script>
8
 
9
- <!-- jsPDF for report generation (no integrity) -->
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
11
  </head>
12
  <body class="bg-gradient-to-br from-slate-950 via-slate-900 to-violet-950 text-white min-h-screen flex flex-col">
@@ -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,14 +302,6 @@
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
-
360
  // DOM references
361
  const textarea = document.getElementById("inputText");
362
  const fileInput = document.getElementById("fileInput");
@@ -556,86 +501,91 @@
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.",
611
- role: "B.Tech Student",
612
- text: "Helps me understand how AI-generated my project reports might look before submission.",
613
- stars: 5
614
- },
615
- {
616
- name: "Priya K.",
617
- role: "AI Research Enthusiast",
618
- text: "The transparent scoring is perfect for explaining AI detection concepts to juniors.",
619
- stars: 5
620
- },
621
- {
622
- name: "Rahul M.",
623
- role: "Content Creator",
624
- text: "Gives a quick signal when my text feels too uniform and AI-like.",
625
- stars: 4
626
- },
627
- {
628
- name: "Sneha R.",
629
- role: "M.Sc. Student",
630
- text: "Very handy example for my seminar on AI ethics and content authenticity.",
631
- stars: 5
632
- },
633
- {
634
- name: "Vikram J.",
635
- role: "Developer",
636
- text: "Exactly the kind of simple, hackable AI-detector UI I wanted for my side project.",
637
- stars: 4
638
- }
639
  ];
640
 
641
  let currentReview = 0;
 
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
  <script src="https://cdn.tailwindcss.com"></script>
8
 
9
+ <!-- jsPDF for backward compatibility (not used for server PDF) -->
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
11
  </head>
12
  <body class="bg-gradient-to-br from-slate-950 via-slate-900 to-violet-950 text-white min-h-screen flex flex-col">
 
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
  // DOM references
306
  const textarea = document.getElementById("inputText");
307
  const fileInput = document.getElementById("fileInput");
 
501
  }
502
  };
503
 
504
+ // Helper to download a blob with filename
505
+ function downloadBlob(blob, filename) {
506
+ const url = URL.createObjectURL(blob);
507
+ const a = document.createElement("a");
508
+ a.href = url;
509
+ a.download = filename || "report.pdf";
510
+ document.body.appendChild(a);
511
+ a.click();
512
+ a.remove();
513
+ setTimeout(() => URL.revokeObjectURL(url), 30000);
514
+ }
515
+
516
+ // Fetch PDF from backend (GET when text, POST when file)
517
+ async function fetchReportPdf({ endpointGet, endpointFile, text, file, defaultFilename }) {
518
+ if (file) {
519
+ const form = new FormData();
520
+ form.append("file", file, file.name);
521
+ const res = await fetch(`${BACKEND_URL}${endpointFile}`, {
522
+ method: "POST",
523
+ headers: { "Authorization": `Bearer ${token}` },
524
+ body: form
525
+ });
526
+ if (!res.ok) {
527
+ const txt = await res.text();
528
+ throw new Error(txt || `Server responded ${res.status}`);
529
+ }
530
+ const blob = await res.blob();
531
+ // try to get filename from content-disposition
532
+ const cd = res.headers.get("content-disposition") || "";
533
+ const m = cd.match(/filename\*?=(?:UTF-8'')?["']?([^;"']+)/i);
534
+ const fname = m ? decodeURIComponent(m[1]) : defaultFilename;
535
+ downloadBlob(blob, fname);
536
  return;
537
+ } else {
538
+ // Use GET with query param (encode)
539
+ const q = encodeURIComponent(text || "");
540
+ const url = `${BACKEND_URL}${endpointGet}?text=${q}`;
541
+ const res = await fetch(url, {
542
+ method: "GET",
543
+ headers: { "Authorization": `Bearer ${token}` }
544
+ });
545
+ if (!res.ok) {
546
+ const txt = await res.text();
547
+ throw new Error(txt || `Server responded ${res.status}`);
548
+ }
549
+ const blob = await res.blob();
550
+ const cd = res.headers.get("content-disposition") || "";
551
+ const m = cd.match(/filename\*?=(?:UTF-8'')?["']?([^;"']+)/i);
552
+ const fname = m ? decodeURIComponent(m[1]) : defaultFilename;
553
+ downloadBlob(blob, fname);
554
  }
555
+ }
556
 
557
+ // PDF download: now calls server-generated PDF
558
+ downloadBtn.onclick = async () => {
559
+ if (!lastResult) {
560
+ alert("Run at least one scan before downloading a report.");
561
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
562
  }
563
 
564
+ try {
565
+ setLoading(true);
566
+ const file = fileInput.files[0] || null;
567
+ await fetchReportPdf({
568
+ endpointGet: "/report/ai",
569
+ endpointFile: "/report/ai-file",
570
+ text: textarea.value,
571
+ file,
572
+ defaultFilename: "TrueWrite_AiReport.pdf"
573
+ });
574
+ } catch (err) {
575
+ console.error(err);
576
+ alert("Failed to download report: " + (err.message || err));
577
+ } finally {
578
+ setLoading(false);
579
  }
 
 
 
 
 
 
 
 
 
 
580
  };
581
 
582
+ // Reviews slider (unchanged)
583
  const reviews = [
584
+ { name: "Aarav S.", role: "B.Tech Student", text: "Helps me understand how AI-generated my project reports might look before submission.", stars: 5 },
585
+ { name: "Priya K.", role: "AI Research Enthusiast", text: "The transparent scoring is perfect for explaining AI detection concepts to juniors.", stars: 5 },
586
+ { name: "Rahul M.", role: "Content Creator", text: "Gives a quick signal when my text feels too uniform and AI-like.", stars: 4 },
587
+ { name: "Sneha R.", role: "M.Sc. Student", text: "Very handy example for my seminar on AI ethics and content authenticity.", stars: 5 },
588
+ { name: "Vikram J.", role: "Developer", text: "Exactly the kind of simple, hackable AI-detector UI I wanted for my side project.", stars: 4 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  ];
590
 
591
  let currentReview = 0;