vivek1192's picture
Fix API URLs to use relative paths for production
4113b5b
import React from 'react';
import { saveAs } from 'file-saver';
// ... (in handleDownload)
import { motion } from 'framer-motion';
const Results = ({ result, onReset }) => {
if (!result) return null;
// Mock score: 0 = Human, 100 = AI
const score = result.score || 0;
const isAI = score > 50;
const handleDownload = async () => {
try {
// Need to pass the original text here.
// Since result doesn't contain the original text by default (optimized away),
// we should ideally have it.
// For now, let's assume `result.text` is available or we pass input props.
// Wait, result only has score/label/ppl.
// We need to pass the text from App.jsx or store it in result.
// Let's assume App.jsx will now pass text in `result` (Need to update App.jsx too if not present)
// Actually, simpler: Let's assume we pass `text` as a prop to Results component for now?
// Or update backend to echo back the text?
// Let's update App.jsx to attach `originalText` to the result object.
const response = await fetch('/api/report/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: result.originalText || "Content not available",
score: score,
label: isAI ? "AI Generated" : "Human Written"
})
});
if (!response.ok) throw new Error("Report generation failed");
const blob = await response.blob();
saveAs(blob, "DetectAI_Report.pdf");
} catch (e) {
alert("Failed to download report: " + e.message);
}
};
return (
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
className="w-full max-w-3xl glass-panel p-8 mt-6 flex flex-col items-center"
>
<h2 className="text-2xl font-bold text-white mb-8">Detection Result</h2>
<div className="relative w-64 h-32 overflow-hidden mb-6">
{/* Gauge Body */}
<div className="absolute top-0 left-0 w-full h-64 rounded-full border-[12px] border-[rgba(255,255,255,0.1)] border-b-transparent rotate-0 box-border pointer-events-none"></div>
{/* Gauge Fill */}
<motion.div
initial={{ rotate: -180 }}
animate={{ rotate: -180 + (score / 100) * 180 }}
transition={{ duration: 1.5, ease: "circOut" }}
className="absolute top-0 left-0 w-full h-64 rounded-full border-[12px] border-b-transparent box-border"
style={{
borderColor: `transparent ${isAI ? '#ef4444' : '#22c55e'} ${isAI ? '#ef4444' : '#22c55e'} transparent`,
transformOrigin: '50% 50%'
}}
></motion.div>
<div className="absolute bottom-0 left-1/2 transform -translate-x-1/2 mb-4 text-center">
<span className="text-4xl font-bold text-white block">{score.toFixed(1)}%</span>
<span className={`text-sm font-uppercase tracking-wider ${isAI ? 'text-red-400' : 'text-green-400'}`}>
{isAI ? 'AI GENERATED' : 'HUMAN WRITTEN'}
</span>
</div>
</div>
<p className="text-secondary text-center max-w-md mb-8">
Our DeBERTa model is <strong>{score.toFixed(1)}%</strong> confident that this content was {isAI ? 'generated by AI' : 'written by a human'}.
</p>
<div className="flex gap-4">
<button
onClick={onReset}
className="px-6 py-2 border border-[rgba(255,255,255,0.2)] rounded-full text-white hover:bg-[rgba(255,255,255,0.05)] transition-colors"
>
Analyze Another
</button>
<button
onClick={handleDownload}
className="px-6 py-2 bg-blue-600 rounded-full text-white hover:bg-blue-500 transition-colors shadow-lg"
>
Download PDF Report
</button>
</div>
</motion.div>
);
};
export default Results;