fix: resolve TypeScript errors and finalize frontend build
Browse files
frontend/src/app/globals.css
CHANGED
|
@@ -64,11 +64,13 @@ input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.25); }
|
|
| 64 |
|
| 65 |
@keyframes spin { to { transform: rotate(360deg); } }
|
| 66 |
@keyframes slide-up { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
|
|
|
|
| 67 |
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
|
| 68 |
@keyframes pulse-border { 0%, 100% { border-color: var(--color-brand-dim); } 50% { border-color: var(--color-brand); } }
|
| 69 |
|
| 70 |
.animate-spin { animation: spin 0.7s linear infinite; }
|
| 71 |
.animate-slide-up { animation: slide-up 0.3s ease; }
|
|
|
|
| 72 |
.animate-shimmer {
|
| 73 |
background: linear-gradient(90deg, var(--color-card) 25%, var(--color-card-hover) 50%, var(--color-card) 75%);
|
| 74 |
background-size: 200% 100%;
|
|
|
|
| 64 |
|
| 65 |
@keyframes spin { to { transform: rotate(360deg); } }
|
| 66 |
@keyframes slide-up { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
|
| 67 |
+
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
|
| 68 |
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
|
| 69 |
@keyframes pulse-border { 0%, 100% { border-color: var(--color-brand-dim); } 50% { border-color: var(--color-brand); } }
|
| 70 |
|
| 71 |
.animate-spin { animation: spin 0.7s linear infinite; }
|
| 72 |
.animate-slide-up { animation: slide-up 0.3s ease; }
|
| 73 |
+
.animate-fade-in { animation: fade-in 0.4s ease; }
|
| 74 |
.animate-shimmer {
|
| 75 |
background: linear-gradient(90deg, var(--color-card) 25%, var(--color-card-hover) 50%, var(--color-card) 75%);
|
| 76 |
background-size: 200% 100%;
|
frontend/src/app/jds/[id]/candidates/[cid]/page.tsx
CHANGED
|
@@ -29,10 +29,15 @@ interface CandidateData {
|
|
| 29 |
parsed_work_experience?: WorkExp[];
|
| 30 |
programming_languages?: string[];
|
| 31 |
backend_frameworks?: string[];
|
|
|
|
| 32 |
gen_ai_experience?: boolean;
|
| 33 |
growth_velocity?: number;
|
| 34 |
looking_for?: string;
|
| 35 |
open_to_working_at?: string;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
is_actively_or_passively_looking?: string;
|
| 37 |
most_recent_company_is_funded?: boolean;
|
| 38 |
most_recent_company_is_product_company?: boolean;
|
|
|
|
| 29 |
parsed_work_experience?: WorkExp[];
|
| 30 |
programming_languages?: string[];
|
| 31 |
backend_frameworks?: string[];
|
| 32 |
+
frontend_technologies?: string[];
|
| 33 |
gen_ai_experience?: boolean;
|
| 34 |
growth_velocity?: number;
|
| 35 |
looking_for?: string;
|
| 36 |
open_to_working_at?: string;
|
| 37 |
+
notice_period?: string;
|
| 38 |
+
time_in_current_company?: number;
|
| 39 |
+
education_status?: string;
|
| 40 |
+
degree?: string;
|
| 41 |
is_actively_or_passively_looking?: string;
|
| 42 |
most_recent_company_is_funded?: boolean;
|
| 43 |
most_recent_company_is_product_company?: boolean;
|
frontend/src/app/jds/[id]/page.tsx
CHANGED
|
@@ -69,13 +69,13 @@ export default function JDDetailPage() {
|
|
| 69 |
// Instance 0ms Array sorting natively!
|
| 70 |
if (baseResults && match) {
|
| 71 |
const totalW = Object.values(nw).reduce((a, b) => a + b, 0);
|
| 72 |
-
const wNorm = totalW > 0 ? Object.fromEntries(Object.entries(nw).map(([k, v]) => [k, v / totalW])) : nw;
|
| 73 |
|
| 74 |
const newRes = baseResults.map(c => {
|
| 75 |
let score = 0;
|
| 76 |
-
const cs = c.component_scores
|
| 77 |
["semantic", "skill", "yoe", "company", "growth", "education"].forEach(k => {
|
| 78 |
-
score += (cs[k]
|
| 79 |
});
|
| 80 |
return { ...c, final_score: score };
|
| 81 |
});
|
|
@@ -256,10 +256,10 @@ export default function JDDetailPage() {
|
|
| 256 |
setWeights(DEFAULT_WEIGHTS);
|
| 257 |
if (baseResults && match) {
|
| 258 |
const totalW = Object.values(DEFAULT_WEIGHTS).reduce((a, b) => a + b, 0);
|
| 259 |
-
const wNorm = totalW > 0 ? Object.fromEntries(Object.entries(DEFAULT_WEIGHTS).map(([k, v]) => [k, v / totalW])) : DEFAULT_WEIGHTS;
|
| 260 |
const newRes = baseResults.map(c => {
|
| 261 |
-
let score = 0; const cs = c.component_scores
|
| 262 |
-
["semantic", "skill", "yoe", "company", "growth", "education"].forEach(k => { score += (cs[k]
|
| 263 |
return { ...c, final_score: score };
|
| 264 |
});
|
| 265 |
newRes.sort((a, b) => b.final_score - a.final_score);
|
|
|
|
| 69 |
// Instance 0ms Array sorting natively!
|
| 70 |
if (baseResults && match) {
|
| 71 |
const totalW = Object.values(nw).reduce((a, b) => a + b, 0);
|
| 72 |
+
const wNorm: Record<string, number> = totalW > 0 ? Object.fromEntries(Object.entries(nw).map(([k, v]) => [k, v / totalW])) : nw;
|
| 73 |
|
| 74 |
const newRes = baseResults.map(c => {
|
| 75 |
let score = 0;
|
| 76 |
+
const cs = c.component_scores as unknown as Record<string, number>;
|
| 77 |
["semantic", "skill", "yoe", "company", "growth", "education"].forEach(k => {
|
| 78 |
+
score += (cs[k] || 0) * (wNorm[k] || 0);
|
| 79 |
});
|
| 80 |
return { ...c, final_score: score };
|
| 81 |
});
|
|
|
|
| 256 |
setWeights(DEFAULT_WEIGHTS);
|
| 257 |
if (baseResults && match) {
|
| 258 |
const totalW = Object.values(DEFAULT_WEIGHTS).reduce((a, b) => a + b, 0);
|
| 259 |
+
const wNorm: Record<string, number> = totalW > 0 ? Object.fromEntries(Object.entries(DEFAULT_WEIGHTS).map(([k, v]) => [k, v / totalW])) : DEFAULT_WEIGHTS;
|
| 260 |
const newRes = baseResults.map(c => {
|
| 261 |
+
let score = 0; const cs = c.component_scores as unknown as Record<string, number>;
|
| 262 |
+
["semantic", "skill", "yoe", "company", "growth", "education"].forEach(k => { score += (cs[k] || 0) * (wNorm[k] || 0); });
|
| 263 |
return { ...c, final_score: score };
|
| 264 |
});
|
| 265 |
newRes.sort((a, b) => b.final_score - a.final_score);
|
frontend/src/app/layout.tsx
CHANGED
|
@@ -26,6 +26,9 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
| 26 |
<Link href="/jds" className="px-3 py-1.5 rounded-lg text-sm text-[var(--color-muted)] hover:text-[var(--color-text)] hover:bg-[var(--color-card)] transition-all">
|
| 27 |
Job Descriptions
|
| 28 |
</Link>
|
|
|
|
|
|
|
|
|
|
| 29 |
</div>
|
| 30 |
</div>
|
| 31 |
</nav>
|
|
|
|
| 26 |
<Link href="/jds" className="px-3 py-1.5 rounded-lg text-sm text-[var(--color-muted)] hover:text-[var(--color-text)] hover:bg-[var(--color-card)] transition-all">
|
| 27 |
Job Descriptions
|
| 28 |
</Link>
|
| 29 |
+
<Link href="/pipeline" className="ml-2 px-3 py-1.5 rounded-lg text-sm font-semibold text-[var(--color-brand-light)] bg-[var(--color-brand-dim)] border border-[var(--color-brand-glow)] hover:bg-[var(--color-brand)] hover:text-white transition-all">
|
| 30 |
+
⚡ Auto Pipeline
|
| 31 |
+
</Link>
|
| 32 |
</div>
|
| 33 |
</div>
|
| 34 |
</nav>
|