Spaces:
Running
Running
Download src/components/ProjectProofCard.tsx from Sarvesh213/getcert-backend: direct link, hf CLI and curl.
- Browser
- Download file 8.2 kB
-
https://huggingface.co/spaces/Sarvesh213/getcert-backend/resolve/main/src/components/ProjectProofCard.tsx
- Command line
-
hf download hf://spaces/Sarvesh213/getcert-backend/src/components/ProjectProofCard.tsx
-
curl -L -o ProjectProofCard.tsx https://huggingface.co/spaces/Sarvesh213/getcert-backend/resolve/main/src/components/ProjectProofCard.tsx
8.2 kB
| import { CheckCircle2, AlertTriangle, FolderGit2, Globe, ShieldCheck } from 'lucide-react'; | |
| import { resolveCanonicalCourseTitle } from '../utils/courseTitleResolver'; | |
| type ProjectProofCardProps = { | |
| project: { | |
| certificateId: string | null; | |
| skill: string; | |
| projectTitle: string | null; | |
| projectType: string | null; | |
| difficultyLevel: 'beginner' | 'intermediate' | 'advanced'; | |
| githubRepoUrl: string | null; | |
| liveDemoUrl: string | null; | |
| finalScore: number; | |
| commitCount: number; | |
| fileCount: number; | |
| passConfidence: number; | |
| trustSignals: { | |
| commitCount: number; | |
| validationPassed: boolean; | |
| readmeScore: number; | |
| projectType: string | null; | |
| }; | |
| validationSummary: { | |
| overallPassed: boolean; | |
| commitPassed: boolean; | |
| readmePassed: boolean; | |
| proofPassed: boolean; | |
| commitCount: number; | |
| fileCount: number; | |
| meaningfulFileCount: number; | |
| readmeRichness: number; | |
| suspiciousSignals: string[]; | |
| } | null; | |
| }; | |
| }; | |
| export function ProjectProofCard({ project }: ProjectProofCardProps) { | |
| const verificationUrl = project.certificateId ? `/verify/${encodeURIComponent(project.certificateId)}` : null; | |
| const displayTitle = project.projectTitle || resolveCanonicalCourseTitle(project.skill); | |
| return ( | |
| <article className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-2xl p-6 shadow-sm font-sans text-slate-900 dark:text-white"> | |
| <div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between"> | |
| <div className="space-y-1"> | |
| <div className="flex items-center gap-2"> | |
| <span className="text-[11px] font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400 bg-slate-100 dark:bg-slate-800 px-2 py-0.5 rounded"> | |
| Level: {project.difficultyLevel} | |
| </span> | |
| <span className="text-xs text-slate-400 dark:text-slate-500"> | |
| {resolveCanonicalCourseTitle(project.skill)} · {project.projectType || 'General'} | |
| </span> | |
| </div> | |
| <h4 className="text-lg font-bold text-slate-900 dark:text-white tracking-tight">{displayTitle}</h4> | |
| </div> | |
| <span className={`inline-flex items-center gap-1.5 px-3 py-1 text-xs font-semibold rounded-full border ${ | |
| project.trustSignals.validationPassed | |
| ? 'bg-emerald-50 dark:bg-emerald-950/40 text-emerald-800 dark:text-emerald-300 border-emerald-200 dark:border-emerald-800' | |
| : 'bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 border-slate-200 dark:border-slate-700' | |
| }`}> | |
| {project.trustSignals.validationPassed ? ( | |
| <> | |
| <CheckCircle2 className="w-3.5 h-3.5" /> | |
| <span>Validation Passed</span> | |
| </> | |
| ) : ( | |
| <> | |
| <AlertTriangle className="w-3.5 h-3.5" /> | |
| <span>Needs Review</span> | |
| </> | |
| )} | |
| </span> | |
| </div> | |
| <div className="mb-5 grid grid-cols-2 gap-3 text-xs md:grid-cols-4"> | |
| <div className="rounded-xl border border-slate-100 dark:border-slate-800 bg-slate-50 dark:bg-slate-800/60 p-3"> | |
| <p className="text-[10px] font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider">Score</p> | |
| <p className="text-xl font-bold text-slate-900 dark:text-white mt-0.5">{project.finalScore}%</p> | |
| </div> | |
| <div className="rounded-xl border border-slate-100 dark:border-slate-800 bg-slate-50 dark:bg-slate-800/60 p-3"> | |
| <p className="text-[10px] font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider">Commits</p> | |
| <p className="text-xl font-bold text-slate-900 dark:text-white mt-0.5">{project.commitCount}</p> | |
| </div> | |
| <div className="rounded-xl border border-slate-100 dark:border-slate-800 bg-slate-50 dark:bg-slate-800/60 p-3"> | |
| <p className="text-[10px] font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider">Files</p> | |
| <p className="text-xl font-bold text-slate-900 dark:text-white mt-0.5">{project.fileCount}</p> | |
| </div> | |
| <div className="rounded-xl border border-slate-100 dark:border-slate-800 bg-slate-50 dark:bg-slate-800/60 p-3"> | |
| <p className="text-[10px] font-semibold text-slate-400 dark:text-slate-500 uppercase tracking-wider">Confidence</p> | |
| <p className="text-xl font-bold text-[#132F50] dark:text-blue-400 mt-0.5">{project.passConfidence}%</p> | |
| </div> | |
| </div> | |
| <div className="mb-5 flex flex-wrap gap-2 text-xs"> | |
| <span className="bg-blue-50 dark:bg-blue-950/40 text-blue-700 dark:text-blue-300 px-2.5 py-1 rounded-lg border border-blue-200 dark:border-blue-800 font-medium"> | |
| README: {project.trustSignals.readmeScore}% | |
| </span> | |
| <span className="bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 px-2.5 py-1 rounded-lg border border-slate-200 dark:border-slate-700 font-medium"> | |
| Type: {project.trustSignals.projectType || 'Standard'} | |
| </span> | |
| <span className="bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 px-2.5 py-1 rounded-lg border border-slate-200 dark:border-slate-700 font-medium"> | |
| Verified Commits: {project.trustSignals.commitCount} | |
| </span> | |
| </div> | |
| {project.validationSummary && project.validationSummary.suspiciousSignals.length > 0 && ( | |
| <div className="mb-5 rounded-xl border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/60 p-4 text-xs text-slate-700 dark:text-slate-300"> | |
| <p className="mb-2 font-semibold uppercase tracking-wider text-slate-800 dark:text-slate-200 flex items-center gap-1.5"> | |
| <AlertTriangle className="w-4 h-4 text-amber-600 inline" /> | |
| <span>Validator Observations</span> | |
| </p> | |
| <ul className="space-y-1 text-xs"> | |
| {project.validationSummary.suspiciousSignals.slice(0, 3).map((signal) => ( | |
| <li key={signal}>• {signal}</li> | |
| ))} | |
| </ul> | |
| </div> | |
| )} | |
| <div className="flex flex-wrap items-center gap-2 pt-4 border-t border-slate-100 dark:border-slate-800"> | |
| {project.githubRepoUrl && ( | |
| <a | |
| href={project.githubRepoUrl} | |
| target="_blank" | |
| rel="noreferrer" | |
| className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-slate-50 hover:bg-slate-100 dark:bg-slate-800 dark:hover:bg-slate-700 text-xs font-semibold text-slate-800 dark:text-slate-200 transition-colors" | |
| > | |
| <FolderGit2 className="w-3.5 h-3.5" /> | |
| <span>Repository</span> | |
| </a> | |
| )} | |
| {project.liveDemoUrl && ( | |
| <a | |
| href={project.liveDemoUrl} | |
| target="_blank" | |
| rel="noreferrer" | |
| className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-slate-50 hover:bg-slate-100 dark:bg-slate-800 dark:hover:bg-slate-700 text-xs font-semibold text-slate-800 dark:text-slate-200 transition-colors" | |
| > | |
| <Globe className="w-3.5 h-3.5" /> | |
| <span>Live Demo</span> | |
| </a> | |
| )} | |
| {verificationUrl && ( | |
| <a | |
| href={verificationUrl} | |
| target="_blank" | |
| rel="noreferrer" | |
| className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-[#132F50] hover:bg-[#0e233d] text-white text-xs font-semibold shadow-2xs transition-colors" | |
| > | |
| <ShieldCheck className="w-3.5 h-3.5" /> | |
| <span>Verify Record</span> | |
| </a> | |
| )} | |
| <span className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-emerald-50 dark:bg-emerald-950/40 text-emerald-800 dark:text-emerald-300 border border-emerald-200 dark:border-emerald-800 text-xs font-semibold ml-auto"> | |
| <CheckCircle2 className="w-3.5 h-3.5" /> | |
| <span>Recruiter Ready</span> | |
| </span> | |
| </div> | |
| </article> | |
| ); | |
| } | |