diff --git a/client/src/pages/DogDetail.jsx b/client/src/pages/DogDetail.jsx
index 7c1f91c..60057d5 100644
--- a/client/src/pages/DogDetail.jsx
+++ b/client/src/pages/DogDetail.jsx
@@ -3,6 +3,7 @@ import { useParams, Link, useNavigate } from 'react-router-dom'
import { Dog, GitBranch, Edit, Upload, Trash2, ArrowLeft, Calendar, Hash, Award } from 'lucide-react'
import axios from 'axios'
import DogForm from '../components/DogForm'
+import { ChampionBadge, ChampionBloodlineBadge } from '../components/ChampionBadge'
function DogDetail() {
const { id } = useParams()
@@ -14,9 +15,7 @@ function DogDetail() {
const [selectedPhoto, setSelectedPhoto] = useState(0)
const fileInputRef = useRef(null)
- useEffect(() => {
- fetchDog()
- }, [id])
+ useEffect(() => { fetchDog() }, [id])
const fetchDog = async () => {
try {
@@ -32,11 +31,9 @@ function DogDetail() {
const handlePhotoUpload = async (e) => {
const file = e.target.files[0]
if (!file) return
-
setUploading(true)
const formData = new FormData()
formData.append('photo', file)
-
try {
await axios.post(`/api/dogs/${id}/photos`, formData, {
headers: { 'Content-Type': 'multipart/form-data' }
@@ -53,7 +50,6 @@ function DogDetail() {
const handleDeletePhoto = async (photoIndex) => {
if (!confirm('Delete this photo?')) return
-
try {
await axios.delete(`/api/dogs/${id}/photos/${photoIndex}`)
fetchDog()
@@ -72,24 +68,20 @@ function DogDetail() {
const birth = new Date(birthDate)
let years = today.getFullYear() - birth.getFullYear()
let months = today.getMonth() - birth.getMonth()
-
- if (months < 0) {
- years--
- months += 12
- }
-
+ if (months < 0) { years--; months += 12 }
if (years === 0) return `${months} month${months !== 1 ? 's' : ''}`
if (months === 0) return `${years} year${years !== 1 ? 's' : ''}`
return `${years}y ${months}m`
}
- if (loading) {
- return
Loading...
- }
+ const hasChampionBlood = (d) =>
+ (d.sire && d.sire.is_champion) || (d.dam && d.dam.is_champion)
- if (!dog) {
- return Dog not found
- }
+ if (loading) return Loading...
+ if (!dog) return Dog not found
+
+ const isChampion = !!dog.is_champion
+ const hasBloodline = !isChampion && hasChampionBlood(dog)
return (
@@ -99,14 +91,18 @@ function DogDetail() {
-
{dog.name}
+
+
{dog.name}
+ {isChampion && }
+ {hasBloodline && }
+
{dog.breed}
- •
+ ·
{dog.sex === 'male' ? 'Male ♂' : 'Female ♀'}
{dog.birth_date && (
<>
- •
+ ·
{calculateAge(dog.birth_date)}
>
)}
@@ -125,12 +121,12 @@ function DogDetail() {
- {/* Photo Section - Compact */}
+ {/* Photo Section */}
Photos
-
-
+
-
+
{dog.photo_urls && dog.photo_urls.length > 0 ? (
<>
- {/* Main Photo */}
-
-
- {/* Thumbnail Strip */}
{dog.photo_urls.length > 1 && (
{dog.photo_urls.map((url, index) => (
@@ -187,9 +179,7 @@ function DogDetail() {
alt={`${dog.name} ${index + 1}`}
onClick={() => setSelectedPhoto(index)}
style={{
- width: '60px',
- height: '60px',
- objectFit: 'cover',
+ width: '60px', height: '60px', objectFit: 'cover',
borderRadius: 'var(--radius-sm)',
cursor: 'pointer',
border: selectedPhoto === index ? '2px solid var(--primary)' : '1px solid var(--border)',
@@ -213,18 +203,26 @@ function DogDetail() {
Details
-
Breed
{dog.breed}
-
Sex
{dog.sex === 'male' ? 'Male ♂' : 'Female ♀'}
-
+
+ Champion
+
+ {isChampion
+ ?
+ : hasBloodline
+ ?
+ : —
+ }
+
+
{dog.birth_date && (
Birth Date
@@ -234,21 +232,18 @@ function DogDetail() {
)}
-
{dog.color && (
Color
{dog.color}
)}
-
{dog.registration_number && (
Registration
{dog.registration_number}
)}
-
{dog.microchip && (
Microchip
@@ -265,9 +260,12 @@ function DogDetail() {
Sire
{dog.sire ? (
-
- {dog.sire.name}
-
+
+
+ {dog.sire.name}
+
+ {dog.sire.is_champion && }
+
) : (
Unknown
)}
@@ -275,9 +273,12 @@ function DogDetail() {
Dam
{dog.dam ? (
-
- {dog.dam.name}
-
+
+
+ {dog.dam.name}
+
+ {dog.dam.is_champion && }
+
) : (
Unknown
)}
@@ -301,19 +302,20 @@ function DogDetail() {
Offspring ({dog.offspring.length})
{dog.offspring.map(child => (
-
{
e.currentTarget.style.borderColor = 'var(--primary)'
@@ -325,7 +327,10 @@ function DogDetail() {
}}
>
{child.name}
-
{child.sex === 'male' ? '♂' : '♀'}
+
+ {child.is_champion && }
+ {child.sex === 'male' ? '♂' : '♀'}
+
))}
@@ -336,14 +341,11 @@ function DogDetail() {
setShowEditModal(false)}
- onSave={() => {
- fetchDog()
- setShowEditModal(false)
- }}
+ onSave={() => { fetchDog(); setShowEditModal(false) }}
/>
)}
)
}
-export default DogDetail
\ No newline at end of file
+export default DogDetail