diff --git a/client/src/pages/DogDetail.jsx b/client/src/pages/DogDetail.jsx
index 60057d5..838c0b4 100644
--- a/client/src/pages/DogDetail.jsx
+++ b/client/src/pages/DogDetail.jsx
@@ -4,6 +4,8 @@ import { Dog, GitBranch, Edit, Upload, Trash2, ArrowLeft, Calendar, Hash, Award
import axios from 'axios'
import DogForm from '../components/DogForm'
import { ChampionBadge, ChampionBloodlineBadge } from '../components/ChampionBadge'
+import ClearanceSummaryCard from '../components/ClearanceSummaryCard'
+import HealthRecordForm from '../components/HealthRecordForm'
function DogDetail() {
const { id } = useParams()
@@ -15,7 +17,13 @@ function DogDetail() {
const [selectedPhoto, setSelectedPhoto] = useState(0)
const fileInputRef = useRef(null)
+ // Health records state
+ const [healthRecords, setHealthRecords] = useState([])
+ const [showHealthForm, setShowHealthForm] = useState(false)
+ const [editingRecord, setEditingRecord] = useState(null)
+
useEffect(() => { fetchDog() }, [id])
+ useEffect(() => { fetchHealth() }, [id])
const fetchDog = async () => {
try {
@@ -28,6 +36,12 @@ function DogDetail() {
}
}
+ const fetchHealth = () => {
+ axios.get(`/api/health/dog/${id}`)
+ .then(r => setHealthRecords(r.data))
+ .catch(() => {})
+ }
+
const handlePhotoUpload = async (e) => {
const file = e.target.files[0]
if (!file) return
@@ -66,7 +80,7 @@ function DogDetail() {
if (!birthDate) return null
const today = new Date()
const birth = new Date(birthDate)
- let years = today.getFullYear() - birth.getFullYear()
+ let years = today.getFullYear() - birth.getFullYear()
let months = today.getMonth() - birth.getMonth()
if (months < 0) { years--; months += 12 }
if (years === 0) return `${months} month${months !== 1 ? 's' : ''}`
@@ -77,10 +91,15 @@ function DogDetail() {
const hasChampionBlood = (d) =>
(d.sire && d.sire.is_champion) || (d.dam && d.dam.is_champion)
- if (loading) return
Loading...
- if (!dog) return Dog not found
+ const openAddHealth = () => { setEditingRecord(null); setShowHealthForm(true) }
+ const openEditHealth = (rec) => { setEditingRecord(rec); setShowHealthForm(true) }
+ const closeHealthForm = () => { setShowHealthForm(false); setEditingRecord(null) }
+ const handleHealthSaved = () => { closeHealthForm(); fetchHealth() }
- const isChampion = !!dog.is_champion
+ if (loading) return Loading...
+ if (!dog) return Dog not found
+
+ const isChampion = !!dog.is_champion
const hasBloodline = !isChampion && hasChampionBlood(dog)
return (
@@ -93,13 +112,13 @@ function DogDetail() {
{dog.name}
- {isChampion && }
+ {isChampion && }
{hasBloodline && }
{dog.breed}
·
- {dog.sex === 'male' ? 'Male ♂' : 'Female ♀'}
+ {dog.sex === 'male' ? 'Male' : 'Female'}
{dog.birth_date && (
<>
·
@@ -180,8 +199,7 @@ function DogDetail() {
onClick={() => setSelectedPhoto(index)}
style={{
width: '60px', height: '60px', objectFit: 'cover',
- borderRadius: 'var(--radius-sm)',
- cursor: 'pointer',
+ borderRadius: 'var(--radius-sm)', cursor: 'pointer',
border: selectedPhoto === index ? '2px solid var(--primary)' : '1px solid var(--border)',
opacity: selectedPhoto === index ? 1 : 0.6,
transition: 'all 0.2s'
@@ -210,7 +228,7 @@ function DogDetail() {
Sex
- {dog.sex === 'male' ? 'Male ♂' : 'Female ♀'}
+ {dog.sex === 'male' ? 'Male' : 'Female'}
Champion
@@ -219,7 +237,7 @@ function DogDetail() {
?
: hasBloodline
?
- : —
+ : —
}
@@ -296,6 +314,49 @@ function DogDetail() {
)}
+ {/* OFA Clearance Summary */}
+
+
+ {/* Health Records List */}
+ {healthRecords.length > 0 && (
+
+
+
+ Health Records ({healthRecords.length})
+
+
+
+
+ {healthRecords.map(rec => (
+
+
+
+ {rec.test_name || (rec.test_type ? rec.test_type.replace(/_/g, ' ') : rec.record_type)}
+
+ {rec.ofa_result && (
+
+ {rec.ofa_result}{rec.ofa_number ? ` · ${rec.ofa_number}` : ''}
+
+ )}
+
+
+ {rec.test_date ? new Date(rec.test_date).toLocaleDateString() : ''}
+
+
+
+ ))}
+
+
+ )}
+
{/* Offspring */}
{dog.offspring && dog.offspring.length > 0 && (
@@ -317,19 +378,19 @@ function DogDetail() {
alignItems: 'center',
gap: '0.5rem'
}}
- onMouseEnter={(e) => {
+ onMouseEnter={e => {
e.currentTarget.style.borderColor = 'var(--primary)'
- e.currentTarget.style.background = 'var(--bg-tertiary)'
+ e.currentTarget.style.background = 'var(--bg-tertiary)'
}}
- onMouseLeave={(e) => {
+ onMouseLeave={e => {
e.currentTarget.style.borderColor = 'var(--border)'
- e.currentTarget.style.background = 'var(--bg-primary)'
+ e.currentTarget.style.background = 'var(--bg-primary)'
}}
>
{child.name}
{child.is_champion && }
- {child.sex === 'male' ? '♂' : '♀'}
+ {child.sex === 'male' ? '' : ''}
))}
@@ -337,6 +398,7 @@ function DogDetail() {
)}
+ {/* Edit Dog Modal */}
{showEditModal && (
{ fetchDog(); setShowEditModal(false) }}
/>
)}
+
+ {/* Health Record Form Modal */}
+ {showHealthForm && (
+
+ )}
)
}