"use client"; import { ALL_DEALBREAKERS, dealbreakerLabel, type Dealbreaker, type ScoringWeights, } from "@/lib/job-search-preferences"; import { MATCH_SCORE_WEIGHTS } from "@/lib/score-display"; export type ScoringControlValues = { scoringWeights: ScoringWeights; dealbreakers: Dealbreaker[]; }; export function scoringControlValuesFromPrefs(opts?: { scoringWeights?: ScoringWeights; dealbreakers?: Dealbreaker[]; }): ScoringControlValues { return { scoringWeights: { role_fit: opts?.scoringWeights?.role_fit ?? MATCH_SCORE_WEIGHTS.role_fit * 10, global_remote: opts?.scoringWeights?.global_remote ?? MATCH_SCORE_WEIGHTS.global_remote * 10, culture_async: opts?.scoringWeights?.culture_async ?? MATCH_SCORE_WEIGHTS.culture_async * 10, contractor_friendly: opts?.scoringWeights?.contractor_friendly ?? MATCH_SCORE_WEIGHTS.contractor_friendly * 10, }, dealbreakers: opts?.dealbreakers ?? [], }; } const WEIGHT_FIELDS: Array<{ key: keyof ScoringWeights; label: string }> = [ { key: "role_fit", label: "Role & skill fit" }, { key: "global_remote", label: "Worldwide remote" }, { key: "culture_async", label: "Async culture" }, { key: "contractor_friendly", label: "Contractor-friendly" }, ]; type Props = { values: ScoringControlValues; onChange: (next: ScoringControlValues) => void; disabled?: boolean; }; export function ScoringControlForm({ values, onChange, disabled = false }: Props) { const setWeight = (key: keyof ScoringWeights, raw: string) => { const n = Number(raw); onChange({ ...values, scoringWeights: { ...values.scoringWeights, [key]: Number.isFinite(n) ? Math.max(0, Math.min(10, n)) : 0, }, }); }; const toggleDealbreaker = (d: Dealbreaker) => { const has = values.dealbreakers.includes(d); onChange({ ...values, dealbreakers: has ? values.dealbreakers.filter((x) => x !== d) : [...values.dealbreakers, d], }); }; return ( <>
Defaults favour role fit and worldwide remote. Values are relative. They do not have to add to 10.
{WEIGHT_FIELDS.map(({ key, label }) => ( ))}Hard rules. A listing that breaks any of these is scored Skip, with an explicit callout.