From d426835b13baf392c492189ec09ab503777e1435 Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 9 Mar 2026 00:44:34 -0500 Subject: [PATCH] Rebuild PedigreeView with interactive tree visualization --- client/src/pages/PedigreeView.jsx | 208 +++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 7 deletions(-) diff --git a/client/src/pages/PedigreeView.jsx b/client/src/pages/PedigreeView.jsx index 328ba25..8d14a5e 100644 --- a/client/src/pages/PedigreeView.jsx +++ b/client/src/pages/PedigreeView.jsx @@ -1,16 +1,210 @@ -import { useParams } from 'react-router-dom' -import { GitBranch } from 'lucide-react' +import { useEffect, useState } from 'react' +import { useParams, useNavigate } from 'react-router-dom' +import { ArrowLeft, GitBranch, AlertCircle, Loader } from 'lucide-react' +import axios from 'axios' +import PedigreeTree from '../components/PedigreeTree' +import { transformPedigreeData, formatCOI, getPedigreeCompleteness } from '../utils/pedigreeHelpers' function PedigreeView() { const { id } = useParams() + const navigate = useNavigate() + const [loading, setLoading] = useState(true) + const [error, setError] = useState('') + const [dog, setDog] = useState(null) + const [pedigreeData, setPedigreeData] = useState(null) + const [coiData, setCoiData] = useState(null) + const [generations, setGenerations] = useState(5) + + useEffect(() => { + fetchPedigreeData() + }, [id, generations]) + + const fetchPedigreeData = async () => { + setLoading(true) + setError('') + + try { + // Fetch pedigree tree data + const pedigreeRes = await axios.get(`/api/pedigree/${id}`) + const dogData = pedigreeRes.data + + setDog(dogData) + + // Transform data for react-d3-tree + const treeData = transformPedigreeData(dogData, generations) + setPedigreeData(treeData) + + // Fetch COI calculation + try { + const coiRes = await axios.get(`/api/pedigree/${id}/coi`) + setCoiData(coiRes.data) + } catch (coiError) { + console.warn('COI calculation unavailable:', coiError) + setCoiData(null) + } + + setLoading(false) + } catch (err) { + console.error('Error fetching pedigree:', err) + setError(err.response?.data?.error || 'Failed to load pedigree data') + setLoading(false) + } + } + + const completeness = pedigreeData ? getPedigreeCompleteness(pedigreeData, generations) : 0 + const coiInfo = formatCOI(coiData?.coi) + + if (loading) { + return ( +
+
+ +

Loading pedigree data...

+
+
+ ) + } + + if (error) { + return ( +
+
+ +

Error Loading Pedigree

+

{error}

+ +
+
+ ) + } return (
-

Pedigree Chart

-
- -

Interactive Pedigree Visualization

-

Coming soon - React D3 Tree integration for dog ID: {id}

+ {/* Header */} +
+ + +
+

+ + {dog?.name}'s Pedigree +

+ {dog?.registration_number && ( +

+ Registration: {dog.registration_number} +

+ )} +
+
+ + {/* Stats Bar */} +
+
+
+
+ Coefficient of Inbreeding +
+
+ + {coiInfo.value} + + + {coiInfo.level} + +
+
+ {coiInfo.description} +
+
+ +
+
+ Pedigree Completeness +
+
+ {completeness}% +
+
+
+
+
+
+
+ +
+
+ Generations Displayed +
+ +
+
+
+ + {/* Pedigree Tree */} +
+ {pedigreeData ? ( + + ) : ( +
+ +

No Pedigree Data Available

+

+ Add parent information to this dog to build the pedigree tree. +

+
+ )} +
+ + {/* Help Text */} +
+
+ 💡 Tip: Click on any ancestor node to navigate to their profile. + Use the zoom controls to explore the tree, or drag to pan around. +
)