Fixes for appointments and My Pets fields.

This commit is contained in:
augmentedpotato
2026-04-14 12:20:48 -06:00
parent 208372c782
commit c2f39c40f0
13 changed files with 570 additions and 193 deletions

View File

@@ -6,6 +6,18 @@ import { useAuth } from "@/context/AuthContext";
const API_BASE = "";
const SPECIES_BREEDS = {
Dog: ["Beagle", "Boxer", "Bulldog", "Chihuahua", "Dachshund", "German Shepherd", "Golden Retriever", "Labrador Retriever", "Poodle", "Rottweiler", "Shih Tzu", "Siberian Husky", "Yorkshire Terrier", "Mixed / Other"],
Cat: ["Abyssinian", "Bengal", "British Shorthair", "Maine Coon", "Persian", "Ragdoll", "Scottish Fold", "Siamese", "Sphynx", "Mixed / Other"],
Bird: ["Canary", "Cockatiel", "Cockatoo", "Finch", "Lovebird", "Macaw", "Parakeet", "Parrot", "Other"],
Rabbit: ["Dutch", "Flemish Giant", "Holland Lop", "Lionhead", "Mini Rex", "Other"],
Hamster: ["Dwarf", "Roborovski", "Syrian", "Other"],
"Guinea Pig": ["Abyssinian", "American", "Peruvian", "Teddy", "Other"],
Reptile: ["Ball Python", "Bearded Dragon", "Blue-tongued Skink", "Corn Snake", "Leopard Gecko", "Other"],
Fish: ["Angelfish", "Betta", "Cichlid", "Clownfish", "Goldfish", "Guppy", "Tetra", "Other"],
Other: ["Other"],
};
export default function ProfilePage() {
const {user, token, loading, logout, refreshUser} = useAuth();
const router = useRouter();
@@ -53,7 +65,7 @@ export default function ProfilePage() {
setLoadingPets(true);
try {
const response = await fetch(`${API_BASE}/api/v1/my-pets`, {
const response = await fetch(`${API_BASE}/api/v1/my-pets?status=Owned`, {
headers: { Authorization: `Bearer ${token}` },
});
@@ -64,25 +76,21 @@ export default function ProfilePage() {
const petData = await response.json();
clearPetImageObjectUrls();
const petsWithResolvedImages = await Promise.all(
(Array.isArray(petData) ? petData : []).map(async (pet) => {
if (!pet.imageUrl) {
return pet;
}
const ownedPets = Array.isArray(petData) ? petData : [];
const petsWithResolvedImages = await Promise.all(
ownedPets.map(async (pet) => {
if (!pet.imageUrl) return pet;
try {
const imageResponse = await fetch(`${API_BASE}${pet.imageUrl}`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!imageResponse.ok) {
return { ...pet, imageUrl: null };
}
if (!imageResponse.ok) return { ...pet, imageUrl: null };
const blob = await imageResponse.blob();
const objectUrl = URL.createObjectURL(blob);
petImageObjectUrlsRef.current.push(objectUrl);
return { ...pet, imageUrl: objectUrl };
} catch {
return { ...pet, imageUrl: null };
@@ -284,14 +292,19 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
}
try {
await fetch(`${API_BASE}/api/v1/my-pets/${id}`, {
const res = await fetch(`${API_BASE}/api/v1/my-pets/${id}`, {
method: "DELETE",
headers: { Authorization: `Bearer ${token}` },
});
if (!res.ok) {
const data = await res.json().catch(() => null);
throw new Error(data?.message || `Failed to remove pet (${res.status})`);
}
loadPets();
}
catch {
catch (err) {
alert(err.message);
}
}
@@ -445,26 +458,32 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
</label>
<label className="appt-label">
Species
<input
className="appt-input"
type="text"
<select
className="appt-select"
value={species}
onChange={(e) => setSpecies(e.target.value)}
onChange={(e) => { setSpecies(e.target.value); setBreed(""); }}
required
maxLength={50}
placeholder="e.g. Dog, Cat, Bird"
/>
>
<option value="">Select a species...</option>
{Object.keys(SPECIES_BREEDS).map((s) => (
<option key={s} value={s}>{s}</option>
))}
</select>
</label>
<label className="appt-label">
Breed (optional)
<input
className="appt-input"
type="text"
Breed
<select
className="appt-select"
value={breed}
onChange={(e) => setBreed(e.target.value)}
maxLength={50}
placeholder="e.g. Golden Retriever"
/>
required
disabled={!species}
>
<option value="">{species ? "Select a breed..." : "Select a species first"}</option>
{(SPECIES_BREEDS[species] || []).map((b) => (
<option key={b} value={b}>{b}</option>
))}
</select>
</label>
<div className="profile-pet-form-actions">
<button type="submit" className="appt-submit-btn" disabled={submitting}>
@@ -514,11 +533,11 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
{pet.breed && <span className="profile-pet-card-detail">{pet.breed}</span>}
</div>
<div className="profile-pet-card-actions">
<button type="button" className="profile-pet-edit-btn" onClick={() => openEditForm(pet)}>Edit</button>
<button type="button" className="profile-pet-delete-btn" onClick={() => handleDeletePet(pet.customerPetId)}>Remove</button>
</div>
</div>
))}
<button type="button" className="profile-pet-edit-btn" onClick={() => openEditForm(pet)}>Edit</button>
<button type="button" className="profile-pet-delete-btn" onClick={() => handleDeletePet(pet.customerPetId)}>Remove</button>
</div>
</div>
))}
</div>
)}
</div>