fix error line
This commit is contained in:
@@ -95,13 +95,14 @@ export default function AIInterviewModal({ open, onClose, application, job, cond
|
||||
setMessages(newMessages);
|
||||
lastUserMessageTime.current = Date.now();
|
||||
await speak(question);
|
||||
} catch (e) {
|
||||
} catch (_e) {
|
||||
setError('Interview connection issue. Please retry.');
|
||||
}
|
||||
}, [jobTitle, speak, language]);
|
||||
|
||||
const startListening = useCallback(() => {
|
||||
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||
const win = /** @type {any} */ (window);
|
||||
const SpeechRecognition = win.SpeechRecognition || win.webkitSpeechRecognition;
|
||||
if (!SpeechRecognition) {
|
||||
setError('Voice input not supported in this browser. Use text mode below.');
|
||||
return;
|
||||
@@ -181,7 +182,7 @@ export default function AIInterviewModal({ open, onClose, application, job, cond
|
||||
} });
|
||||
setEvaluation(result);
|
||||
setPhase('done');
|
||||
} catch (e) {
|
||||
} catch (_e) {
|
||||
setError('Evaluation failed. Please try again.');
|
||||
setPhase('active');
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ const STATUS_STYLES = {
|
||||
rejected: { badge: 'bg-[#FEE2E2] text-[#991B1B]', label: 'Rejected', card: 'bg-white border-[#E5E7EB]' },
|
||||
};
|
||||
|
||||
function getInitials(name) {
|
||||
function _getInitials(name) {
|
||||
return name?.split(' ').map(w => w[0]).slice(0, 2).join('').toUpperCase() || '??';
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ function ScoreRing({ score }) {
|
||||
);
|
||||
}
|
||||
|
||||
/** @param {any} props */
|
||||
export default function CandidateCard({ application, jobTitle, rank, onAction, onMessage, onCall, onSchedule, onDecline, onDelete, onHire }) {
|
||||
const navigate = useNavigate();
|
||||
const position = jobTitle || application.job_title || '';
|
||||
@@ -116,7 +117,7 @@ export default function CandidateCard({ application, jobTitle, rank, onAction, o
|
||||
try {
|
||||
await base44.entities.JobApplication.update(application.id, { status: 'rejected' });
|
||||
toast.success(`${application.applicant_name} declined`);
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
toast.error('Failed to decline candidate');
|
||||
}
|
||||
}
|
||||
@@ -130,7 +131,7 @@ export default function CandidateCard({ application, jobTitle, rank, onAction, o
|
||||
try {
|
||||
await base44.entities.JobApplication.delete(application.id);
|
||||
toast.success(`${application.applicant_name} deleted`);
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
toast.error('Failed to delete candidate');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ const METRIC_CONFIG = [
|
||||
{ key: 'employer_requirements', label: 'Req Match', Icon: Check },
|
||||
];
|
||||
|
||||
function MetricPill({ label, value, Icon }) {
|
||||
/** @param {any} props */
|
||||
function _MetricPill({ label, value, Icon }) {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-white border border-[#E5E7EB]">
|
||||
<Icon className="w-3 h-3 text-[#9CA3AF]" strokeWidth={2} />
|
||||
|
||||
@@ -2,7 +2,8 @@ import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
|
||||
function Stage({ label, value, sub, accent, to }) {
|
||||
/** @param {any} props */
|
||||
function Stage({ label, value, sub = '', accent = false, to = null }) {
|
||||
const body = (
|
||||
<div className="text-center sm:text-left">
|
||||
<div className="text-[11px] font-medium uppercase tracking-wider text-[#94A3B8]">{label}</div>
|
||||
|
||||
@@ -332,7 +332,8 @@ export function MatchedCandidates({ job, profiles = [], courses = [], applicatio
|
||||
* `MatchedCandidates` rather than inside it: two audiences, two components, one
|
||||
* scoring function that cannot drift between them.
|
||||
*/
|
||||
export function YourSkillFit({ job, held, className }) {
|
||||
/** @param {any} props */
|
||||
export function YourSkillFit({ job, held, className = '' }) {
|
||||
const match = matchPosition(job, held);
|
||||
if (!match) return null;
|
||||
const tone = TONE[match.tone] || TONE.warning;
|
||||
|
||||
@@ -83,6 +83,7 @@ function ScoreFactor({ label, value }) {
|
||||
);
|
||||
}
|
||||
|
||||
/** @param {any} props */
|
||||
export default function TalentDetailModal({ open, onClose, profile, onContact, onSchedule, onHire, matchScore, matchReasons }) {
|
||||
if (!profile) return null;
|
||||
const badges = profile.earned_badges || [];
|
||||
|
||||
@@ -92,9 +92,17 @@ function SkillPath({ state }) {
|
||||
);
|
||||
}
|
||||
|
||||
/** @param {any} props */
|
||||
export function VerifiedSkills({
|
||||
pageId, profile, profiles = [], courses = [], positions = [], email, customSources = [],
|
||||
onOpenTraining, className,
|
||||
pageId = '',
|
||||
profile = null,
|
||||
profiles = [],
|
||||
courses = [],
|
||||
positions = [],
|
||||
email = '',
|
||||
customSources = [],
|
||||
onOpenTraining = null,
|
||||
className = '',
|
||||
}) {
|
||||
/* Accepts a profile or the email of one, so a candidate record — which is an
|
||||
application, not a worker profile — can be matched to the person behind it. */
|
||||
@@ -126,7 +134,7 @@ export function VerifiedSkills({
|
||||
if (!worker) return [];
|
||||
const byId = new Map(courses.map((c) => [c.id, c]));
|
||||
return [...(worker.completed_courses || [])]
|
||||
.sort((a, b) => new Date(b.completed_date) - new Date(a.completed_date))
|
||||
.sort((a, b) => new Date(b.completed_date).getTime() - new Date(a.completed_date).getTime())
|
||||
.slice(0, 3)
|
||||
.map((entry) => {
|
||||
const course = byId.get(entry.course_id);
|
||||
|
||||
@@ -172,7 +172,8 @@ const initialsFor = (name) => {
|
||||
* hierarchy this card is meant to establish. Values share one ink colour so no
|
||||
* single signal shouts louder than the rest.
|
||||
*/
|
||||
function SupportingSignal({ label, value, suffix, icon: Icon }) {
|
||||
/** @param {any} props */
|
||||
function SupportingSignal({ label, value, suffix = '', icon: Icon = null }) {
|
||||
const shown = value != null && value !== '' ? value : '—';
|
||||
return (
|
||||
<div className="flex items-baseline justify-between gap-3">
|
||||
|
||||
@@ -96,7 +96,8 @@ function FactorPill({ label, value }) {
|
||||
);
|
||||
}
|
||||
|
||||
function ReportRow({ icon: Icon, label, value, tone }) {
|
||||
/** @param {any} props */
|
||||
function ReportRow({ icon: Icon, label, value, tone = 'neutral' }) {
|
||||
const valColor = tone === 'verified' ? 'text-[#10B981]' : tone === 'amber' ? 'text-[#D97706]' : 'text-[#0F172A]';
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-3 py-2 border-b border-white/60 last:border-0">
|
||||
@@ -117,7 +118,7 @@ export default function IdentityCareerCard({ profile }) {
|
||||
|
||||
const score = getTalentScore(profile);
|
||||
const band = getScoreBand(score);
|
||||
const growth = getGrowth(profile);
|
||||
const _growth = getGrowth(profile);
|
||||
const esat = getESAT(profile);
|
||||
const fico = toFICO(score);
|
||||
const shortId = (profile.id || '').slice(-6).toUpperCase();
|
||||
|
||||
@@ -29,7 +29,8 @@ function marketRange(profile = {}) {
|
||||
return `$${low}-$${low + 4}/hr`;
|
||||
}
|
||||
|
||||
function Field({ label, value, sub, accent }) {
|
||||
/** @param {any} props */
|
||||
function Field({ label, value, sub = '', accent = false }) {
|
||||
return (
|
||||
<div>
|
||||
<p className="text-[11px] uppercase tracking-wide text-[#6B7280]">{label}</p>
|
||||
@@ -68,7 +69,8 @@ function Factor({ label, value, weight }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function TalentHero({ profile, jobRecs = [], nextCourse, openOwliver }) {
|
||||
/** @param {any} props */
|
||||
export default function TalentHero({ profile, _jobRecs = [], nextCourse = null, openOwliver = null }) {
|
||||
const score = getTalentScore(profile);
|
||||
const factors = getFactors(profile);
|
||||
const first = (profile.full_name || 'there').split(' ')[0];
|
||||
|
||||
Reference in New Issue
Block a user