AuthenticityScore.tsx 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import React from 'react';
  2. import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip } from 'recharts';
  3. interface AuthenticityScoreProps {
  4. videoVerificationScore: number;
  5. socialBindingScore: number;
  6. cloneMaturityScore: number;
  7. }
  8. const ScoreBreakdownBar: React.FC<{ label: string; score: number; maxScore: number; color: string }> = ({ label, score, maxScore, color }) => {
  9. const colorVariants: {[key: string]: string} = {
  10. 'text-blue-500': 'from-blue-400 to-blue-600',
  11. 'text-indigo-500': 'from-indigo-400 to-indigo-600',
  12. 'text-green-500': 'from-green-400 to-green-600',
  13. }
  14. return (
  15. <div>
  16. <div className="flex justify-between items-center mb-1">
  17. <span className="text-sm font-medium text-slate-600">{label}</span>
  18. <span className={`text-sm font-bold ${color}`}>{score} / {maxScore}</span>
  19. </div>
  20. <div className="w-full bg-slate-200 rounded-full h-2.5">
  21. <div className={`bg-gradient-to-r ${colorVariants[color] || 'from-slate-400 to-slate-600'} h-2.5 rounded-full`} style={{ width: `${(score / maxScore) * 100}%` }}></div>
  22. </div>
  23. </div>
  24. );
  25. };
  26. const AuthenticityScore: React.FC<AuthenticityScoreProps> = ({ videoVerificationScore, socialBindingScore, cloneMaturityScore }) => {
  27. const totalScore = videoVerificationScore + socialBindingScore + cloneMaturityScore;
  28. const maxTotalScore = 120; // 15 + 45 + 60
  29. const scoreData = [
  30. { name: 'Score', value: totalScore },
  31. { name: 'Remaining', value: maxTotalScore - totalScore },
  32. ];
  33. const COLORS = ['#3b82f6', '#e5e7eb'];
  34. return (
  35. <div className="bg-white rounded-2xl border border-slate-200 p-6">
  36. <h2 className="text-xl font-bold text-slate-800 mb-4 text-center">Authenticity Score</h2>
  37. <div className="flex flex-col md:flex-row items-center gap-6 md:gap-8">
  38. <div className="w-48 h-48 relative">
  39. <ResponsiveContainer width="100%" height="100%">
  40. <PieChart>
  41. <Pie
  42. data={scoreData}
  43. cx="50%"
  44. cy="50%"
  45. innerRadius={60}
  46. outerRadius={80}
  47. startAngle={90}
  48. endAngle={450}
  49. paddingAngle={0}
  50. dataKey="value"
  51. cornerRadius={10}
  52. >
  53. {scoreData.map((entry, index) => (
  54. <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} stroke="none"/>
  55. ))}
  56. </Pie>
  57. <Tooltip formatter={(value: number, name: string) => [value, '']} />
  58. </PieChart>
  59. </ResponsiveContainer>
  60. <div className="absolute inset-0 flex flex-col items-center justify-center">
  61. <span className="text-4xl font-extrabold text-blue-600">{totalScore}</span>
  62. <span className="text-slate-500">/ {maxTotalScore}</span>
  63. </div>
  64. </div>
  65. <div className="flex-1 w-full space-y-4">
  66. <ScoreBreakdownBar label="Video Verification" score={videoVerificationScore} maxScore={15} color="text-green-500" />
  67. <ScoreBreakdownBar label="Social Account Binding" score={socialBindingScore} maxScore={45} color="text-blue-500" />
  68. <ScoreBreakdownBar label="Digital Clone Maturity" score={cloneMaturityScore} maxScore={60} color="text-indigo-500" />
  69. </div>
  70. </div>
  71. </div>
  72. );
  73. };
  74. export default AuthenticityScore;