import React, { useRef, useState } from 'react'; import html2canvas from 'html2canvas'; import { Wallet, Smartphone, Image as ImageIcon, ShieldCheck, Briefcase, Sparkles, QrCode, Download, Check, Info, RefreshCw } from 'lucide-react'; import { toast } from 'react-hot-toast'; import { Image } from '@/components/ui/image'; import { getTalentScore, getScoreBand, getGrowth } from '@/lib/talentHome'; const clamp = (n, min = 0, max = 100) => Math.max(min, Math.min(max, Math.round(Number(n) || 0))); // Employee Satisfaction — composite of attendance, performance, client & supervisor ratings export function getESAT(profile = {}) { const att = clamp(profile.attendance_score ?? 100); const perf = clamp(profile.performance_score); const client = ((Number(profile.client_rating) || 0) / 5) * 100; const sup = ((Number(profile.supervisor_rating) || 0) / 5) * 100; const hasRatings = client > 0 || sup > 0; if (!hasRatings) return clamp(att * 0.6 + perf * 0.4); return clamp(att * 0.3 + perf * 0.25 + client * 0.225 + sup * 0.225); } // Display the career score on a FICO-style 300–850 scale ("like checking your credit score") const toFICO = (s) => 300 + Math.round((clamp(s) / 100) * 550); function buildVCard(profile) { const name = profile.full_name || 'KROW Talent'; const [first, ...rest] = name.split(' '); const last = rest.join(' '); const lines = [ 'BEGIN:VCARD', 'VERSION:3.0', `N:${last};${first};;;`, `FN:${name}`, profile.current_position ? `TITLE:${profile.current_position}` : '', profile.phone ? `TEL;TYPE=CELL:${profile.phone}` : '', profile.email ? `EMAIL:${profile.email}` : '', profile.address ? `ADR:;;${profile.address};;;;` : '', `URL:https://krow.app/me`, `NOTE:KROW ID ${(profile.id || '').slice(-6).toUpperCase()} · Talent Score ${profile.krow_score || 0}`, 'END:VCARD', ].filter(Boolean); return lines.join('\n'); } function download(filename, content, type) { const blob = new Blob([content], { type }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); } const BLUE = '#0055FF'; const TRACK = '#E1E5E9'; const ARC_R = 64; const CX = 80; const CY = 80; function arcPoint(p) { const ang = Math.PI - p * Math.PI; return { x: CX + ARC_R * Math.cos(ang), y: CY - ARC_R * Math.sin(ang) }; } function arcPath(startP, endP) { const a = arcPoint(startP); const b = arcPoint(endP); const large = endP - startP > 0.5 ? 1 : 0; return `M ${a.x} ${a.y} A ${ARC_R} ${ARC_R} 0 ${large} 1 ${b.x} ${b.y}`; } function Gauge({ fico }) { const pct = Math.max(0, Math.min(1, (fico - 300) / 550)); const gap = 0.02; const filledEnd = Math.max(gap, Math.min(1 - gap, pct)); const marker = arcPoint(filledEnd); return (
KROW ID · {shortId}
{title}
Score factors
{job.role || 'Role'}
{job.company || 'Company'}