Fix profile images

This commit is contained in:
augmentedpotato
2026-04-02 09:32:42 -06:00
parent a3e5e6701e
commit cfd5a7c8cd
2 changed files with 66 additions and 19 deletions

View File

@@ -615,15 +615,7 @@ function AppointmentsPage() {
{submitting ? "Booking..." : isAdoptionService ? "Schedule Adoption Visit" : "Book Appointment"}
</button>
</form>
) : (
<div className="appt-form">
<h2 className="appt-form-title">Appointment Booking</h2>
<div className="appt-service-info">
<p>Web appointment booking is currently available for customer accounts only.</p>
<p>Admin and staff accounts can still review appointment activity below.</p>
</div>
</div>
)}
) : null}
<div className="appt-history">
<h2 className="appt-form-title">{canBookAppointments ? "Your Appointments" : "Appointments"}</h2>

View File

@@ -1,6 +1,6 @@
"use client";
import { useEffect, useState, useCallback } from "react";
import { useEffect, useState, useCallback, useRef } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "@/context/AuthContext";
@@ -9,6 +9,7 @@ const API_BASE = "";
export default function ProfilePage() {
const {user, token, loading, logout, refreshUser} = useAuth();
const router = useRouter();
const petImageObjectUrlsRef = useRef([]);
const [pets, setPets] = useState([]);
const [loadingPets, setLoadingPets] = useState(false);
@@ -25,6 +26,13 @@ export default function ProfilePage() {
const [profileSuccess, setProfileSuccess] = useState(null);
const [avatarSubmitting, setAvatarSubmitting] = useState(false);
const clearPetImageObjectUrls = useCallback(() => {
for (const objectUrl of petImageObjectUrlsRef.current) {
URL.revokeObjectURL(objectUrl);
}
petImageObjectUrlsRef.current = [];
}, []);
useEffect(() => {
if (!loading && !user) {
router.replace(`/login?next=${encodeURIComponent("/profile")}`);
@@ -40,17 +48,64 @@ export default function ProfilePage() {
});
}, [user]);
const loadPets = useCallback(() => {
const loadPets = useCallback(async () => {
if (!token) return;
setLoadingPets(true);
fetch(`${API_BASE}/api/v1/my-pets`, {
headers: { Authorization: `Bearer ${token}` },
})
.then((r) => r.json())
.then(setPets)
.catch(() => {})
.finally(() => setLoadingPets(false));
}, [token]);
try {
const response = await fetch(`${API_BASE}/api/v1/my-pets`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) {
throw new Error(`Request failed (${response.status})`);
}
const petData = await response.json();
clearPetImageObjectUrls();
const petsWithResolvedImages = await Promise.all(
(Array.isArray(petData) ? petData : []).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 };
}
const blob = await imageResponse.blob();
const objectUrl = URL.createObjectURL(blob);
petImageObjectUrlsRef.current.push(objectUrl);
return { ...pet, imageUrl: objectUrl };
} catch {
return { ...pet, imageUrl: null };
}
})
);
setPets(petsWithResolvedImages);
}
catch {
}
finally {
setLoadingPets(false);
}
}, [token, clearPetImageObjectUrls]);
useEffect(() => {
return () => {
clearPetImageObjectUrls();
};
}, [clearPetImageObjectUrls]);
useEffect(() => {
if (user?.role === "CUSTOMER") {