Initial commit

This commit is contained in:
2026-08-07 23:53:15 +05:30
commit 90f14a73b2
222 changed files with 35000 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { motion } from 'framer-motion';
import {
Fingerprint, GraduationCap, Mic, BadgeCheck, Handshake, Briefcase,
LineChart, Star, TrendingUp, Crown, Presentation, Repeat, ArrowRight,
} from 'lucide-react';
// The Credit Bureau for Human Talent — the career flywheel.
const STEPS = [
{ key: 'identity', label: 'Create Identity', to: '/identity', icon: Fingerprint },
{ key: 'learn', label: 'Learn', to: '/university', icon: GraduationCap },
{ key: 'interview', label: 'Interview', to: '/owliver', icon: Mic },
{ key: 'verify', label: 'Verify Skills', to: '/identity', icon: BadgeCheck },
{ key: 'hired', label: 'Get Hired', to: '/apply', icon: Handshake },
{ key: 'work', label: 'Work', to: '/me', icon: Briefcase },
{ key: 'track', label: 'Track Performance', to: '/me', icon: LineChart },
{ key: 'reputation', label: 'Earn Reputation', to: '/me', icon: Star },
{ key: 'promoted', label: 'Get Promoted', to: '/university', icon: TrendingUp },
{ key: 'leader', label: 'Become Leader', to: '/university', icon: Crown },
{ key: 'train', label: 'Train Others', to: '/university', icon: Presentation },
{ key: 'repeat', label: 'Repeat', to: '/university', icon: Repeat, loop: true },
];
export function stepStatus(profile, apps = []) {
const hired = apps.some(a => a.status === 'hired');
const worked = (profile.experience || []).length > 0 || hired;
const isDone = {
identity: !!profile.selfie_url && (profile.skills || []).length > 0,
learn: (profile.completed_courses || []).length > 0,
interview: (profile.ai_interview_score || 0) > 0 || !!(profile.personality || profile.strengths?.length),
verify: (profile.certifications || []).length > 0 || (profile.earned_badges || []).length > 0,
hired,
work: worked,
track: (profile.performance_score || 0) > 0 || (profile.attendance_score || 0) > 0 && worked,
reputation: (profile.client_rating || 0) > 0 || (profile.supervisor_rating || 0) > 0 || (profile.krow_score || 0) >= 50,
promoted: (profile.leadership_potential || 0) >= 40,
leader: (profile.leadership_potential || 0) >= 70,
train: (profile.leadership_potential || 0) >= 85 && (profile.completed_courses || []).length >= 3,
repeat: false,
};
return isDone;
}
export default function TalentLoop({ profile, applications = [] }) {
const done = stepStatus(profile, applications);
const reached = STEPS.filter(s => done[s.key]).length;
const current = STEPS.find(s => !done[s.key]) || STEPS[STEPS.length - 1];
const progress = Math.round((reached / (STEPS.length - 1)) * 100);
return (
<section className="glass-card border border-white/60 rounded-2xl p-6 sm:p-8 shadow-sm">
<div className="flex items-end justify-between flex-wrap gap-3 mb-1">
<div>
<span className="text-[11px] font-medium uppercase tracking-[0.18em] text-[#0A39DF]">The Talent Loop</span>
<h2 className="text-[22px] font-heading font-bold text-[#0F172A] mt-1 tracking-tight">Build your reputation. Not just your resume.</h2>
</div>
<span className="text-[12px] text-[#64748B]">{reached}/{STEPS.length - 1} stages</span>
</div>
<div className="h-1.5 bg-[#EEF2F7] rounded-full overflow-hidden mt-4 mb-7">
<motion.div
initial={{ width: 0 }}
animate={{ width: `${progress}%` }}
transition={{ duration: 0.8, ease: 'easeOut' }}
className="h-full bg-[#0A39DF] rounded-full"
/>
</div>
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3">
{STEPS.map((s, i) => {
const isDone = done[s.key];
const isCurrent = s.key === current.key && !s.loop;
const Icon = s.icon;
return (
<Link
key={s.key}
to={s.to}
className={`group relative flex flex-col items-start gap-2 rounded-xl border p-3 transition-all ${
isDone
? 'bg-[#0A39DF] border-[#0A39DF] text-white'
: isCurrent
? 'bg-white border-[#0A39DF] ring-2 ring-[#0A39DF]/20'
: 'bg-white border-[#E5E7EB] hover:border-[#0A39DF]/50'
}`}
>
<div className="flex items-center justify-between w-full">
<span className={`text-[10px] font-semibold ${isDone ? 'text-white/70' : 'text-[#94A3B8]'}`}>{String(i + 1).padStart(2, '0')}</span>
{s.loop && <Repeat className={`w-3.5 h-3.5 ${isDone ? 'text-white/70' : 'text-[#94A3B8]'}`} />}
</div>
<Icon className={`w-5 h-5 ${isDone ? 'text-white' : isCurrent ? 'text-[#0A39DF]' : 'text-[#64748B]'}`} />
<span className={`text-[12px] font-medium leading-tight ${isDone ? 'text-white' : isCurrent ? 'text-[#0A39DF]' : 'text-[#334155]'}`}>
{s.label}
</span>
</Link>
);
})}
</div>
<div className="flex items-center justify-between gap-3 mt-6 pt-5 border-t border-[#EEF2F7] flex-wrap">
<div>
<p className="text-[11px] text-[#94A3B8] font-medium">UP NEXT</p>
<p className="text-[15px] font-semibold text-[#0F172A]">{current.label}</p>
</div>
<Link
to={current.to}
className="inline-flex items-center gap-1.5 text-[13px] font-semibold text-[#0A39DF] hover:gap-2.5 transition-all"
>
Continue <ArrowRight className="w-4 h-4" />
</Link>
</div>
</section>
);
}