diff --git a/client/src/pages/PairingSimulator.jsx b/client/src/pages/PairingSimulator.jsx index 9633f3e..047f708 100644 --- a/client/src/pages/PairingSimulator.jsx +++ b/client/src/pages/PairingSimulator.jsx @@ -1,5 +1,5 @@ -import { useState, useEffect } from 'react' -import { FlaskConical, AlertTriangle, CheckCircle, XCircle, GitMerge } from 'lucide-react' +import { useState, useEffect, useCallback } from 'react' +import { FlaskConical, AlertTriangle, CheckCircle, XCircle, GitMerge, ShieldAlert } from 'lucide-react' export default function PairingSimulator() { const [dogs, setDogs] = useState([]) @@ -9,6 +9,8 @@ export default function PairingSimulator() { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const [dogsLoading, setDogsLoading] = useState(true) + const [relationWarning, setRelationWarning] = useState(null) + const [relationChecking, setRelationChecking] = useState(false) useEffect(() => { fetch('/api/dogs') @@ -20,7 +22,39 @@ export default function PairingSimulator() { .catch(() => setDogsLoading(false)) }, []) - const males = dogs.filter(d => d.sex === 'male') + // Check for direct relation whenever both sire and dam are selected + const checkRelation = useCallback(async (sid, did) => { + if (!sid || !did) { + setRelationWarning(null) + return + } + setRelationChecking(true) + try { + const res = await fetch(`/api/pedigree/relations/${sid}/${did}`) + const data = await res.json() + setRelationWarning(data.related ? data.relationship : null) + } catch { + setRelationWarning(null) + } finally { + setRelationChecking(false) + } + }, []) + + function handleSireChange(e) { + const val = e.target.value + setSireId(val) + setResult(null) + checkRelation(val, damId) + } + + function handleDamChange(e) { + const val = e.target.value + setDamId(val) + setResult(null) + checkRelation(sireId, val) + } + + const males = dogs.filter(d => d.sex === 'male') const females = dogs.filter(d => d.sex === 'female') async function handleSimulate(e) { @@ -48,13 +82,13 @@ export default function PairingSimulator() { } function RiskBadge({ coi, recommendation }) { - const isLow = coi < 5 - const isMed = coi >= 5 && coi < 10 + const isLow = coi < 5 + const isMed = coi >= 5 && coi < 10 const isHigh = coi >= 10 return (
- {isLow && } - {isMed && } + {isLow && } + {isMed && } {isHigh && } {recommendation}
@@ -84,7 +118,7 @@ export default function PairingSimulator() { setDamId(e.target.value)} + onChange={handleDamChange} required disabled={dogsLoading} > @@ -121,10 +155,30 @@ export default function PairingSimulator() { + {/* Direct-relation warning banner */} + {relationChecking && ( +

Checking relationship…

+ )} + {!relationChecking && relationWarning && ( +
+ +
+

Direct Relation Detected

+

+ {relationWarning}. COI will reflect the high inbreeding coefficient for this pairing. +

+
+
+ )} +