From a1ec3e728b591b0b93620136b8b552298c26bbc0 Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Thu, 16 Apr 2026 07:55:13 -0600 Subject: [PATCH] fix six app bugs --- .../petshop/backend/controller/AiChatController.java | 3 ++- .../backend/repository/AppointmentRepository.java | 3 +++ .../com/petshop/backend/repository/PetRepository.java | 1 + .../petshop/backend/service/AppointmentService.java | 11 +++++++++++ web/app/ai-chat/page.js | 9 ++------- web/app/chat/page.js | 5 ----- web/app/globals.css | 2 ++ 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/backend/src/main/java/com/petshop/backend/controller/AiChatController.java b/backend/src/main/java/com/petshop/backend/controller/AiChatController.java index ba08b418..f65dbaf0 100644 --- a/backend/src/main/java/com/petshop/backend/controller/AiChatController.java +++ b/backend/src/main/java/com/petshop/backend/controller/AiChatController.java @@ -56,7 +56,8 @@ public class AiChatController { List userPets; try { - userPets = petRepository.findAllByOwner_IdOrderByPetNameAsc(user.getId()); + userPets = petRepository.findAllByOwner_IdAndPetStatusInOrderByPetNameAsc( + user.getId(), List.of("Adopted", "Owned")); } catch (Exception e) { diff --git a/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java b/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java index e18a007a..59243df2 100644 --- a/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/AppointmentRepository.java @@ -53,5 +53,8 @@ public interface AppointmentRepository extends JpaRepository List findByPet_Id(Long petId); + @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.pet.petId = :petId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')") + List findByPetIdAndAppointmentDate(@Param("petId") Long petId, @Param("date") LocalDate date); + List findByAppointmentDateAndAppointmentStatusIgnoreCase(LocalDate date, String status); } diff --git a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java index 9358fb72..e294898f 100644 --- a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java @@ -37,6 +37,7 @@ public interface PetRepository extends JpaRepository { List findAdoptablePetsByStore(@Param("storeId") Long storeId); List findAllByOwner_IdOrderByPetNameAsc(Long ownerId); + List findAllByOwner_IdAndPetStatusInOrderByPetNameAsc(Long ownerId, List statuses); Optional findByIdAndOwner_Id(Long id, Long ownerId); @Lock(LockModeType.PESSIMISTIC_WRITE) diff --git a/backend/src/main/java/com/petshop/backend/service/AppointmentService.java b/backend/src/main/java/com/petshop/backend/service/AppointmentService.java index 999568a8..efc5d2c6 100644 --- a/backend/src/main/java/com/petshop/backend/service/AppointmentService.java +++ b/backend/src/main/java/com/petshop/backend/service/AppointmentService.java @@ -132,6 +132,7 @@ public class AppointmentService { validateStoreAccess(store.getStoreId(), authenticatedUser); validatePetServiceCompatibility(pet, service); validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), null); + validatePetAvailability(pet, service, request.getAppointmentDate(), request.getAppointmentTime(), null); Appointment appointment = new Appointment(); appointment.setCustomer(customer); @@ -172,6 +173,7 @@ public class AppointmentService { validateStoreAccess(store.getStoreId(), authenticatedUser); validatePetServiceCompatibility(pet, service); validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), id); + validatePetAvailability(pet, service, request.getAppointmentDate(), request.getAppointmentTime(), id); appointment.setCustomer(customer); appointment.setStore(store); @@ -387,6 +389,15 @@ public class AppointmentService { return true; } + private void validatePetAvailability(Pet pet, com.petshop.backend.entity.Service service, LocalDate date, LocalTime time, Long appointmentIdToIgnore) { + if (pet == null) return; + List existingAppointments = appointmentRepository + .findByPetIdAndAppointmentDate(pet.getPetId(), date); + if (!isSlotAvailable(existingAppointments, service, time, appointmentIdToIgnore)) { + throw new IllegalArgumentException("This pet already has an appointment during this time slot"); + } + } + private void validateSpeciesServiceCompatibility(Pet pet, com.petshop.backend.entity.Service service) { if (pet == null || service == null) return; String species = pet.getPetSpecies(); diff --git a/web/app/ai-chat/page.js b/web/app/ai-chat/page.js index 8bfe0bb8..0cdd6429 100644 --- a/web/app/ai-chat/page.js +++ b/web/app/ai-chat/page.js @@ -45,9 +45,9 @@ function AiChatPage() { lastScrolledIdRef.current = lastMsg.id; const area = messagesAreaRef.current; if (!area) return; - const nearBottom = area.scrollHeight - area.scrollTop - area.clientHeight < 150; + const nearBottom = area.scrollHeight - area.scrollTop - area.clientHeight < 80; if (nearBottom) { - messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + area.scrollTop = area.scrollHeight; } }, [messages]); @@ -347,11 +347,6 @@ function AiChatPage() { if (pollRef.current) clearInterval(pollRef.current); setMessages([]); setError(null); - setLoadingConv(true); - await fetchConversation(convId); - await fetchMessages(convId); - setLoadingConv(false); - startPolling(convId); router.replace(`/ai-chat?id=${convId}`, { scroll: false }); } diff --git a/web/app/chat/page.js b/web/app/chat/page.js index 7feeb5dd..a566a487 100644 --- a/web/app/chat/page.js +++ b/web/app/chat/page.js @@ -352,11 +352,6 @@ function ChatPage() { if (pollRef.current) clearInterval(pollRef.current); setMessages([]); setError(null); - setLoadingConv(true); - await fetchConversation(convId); - await fetchMessages(convId); - setLoadingConv(false); - startPolling(convId); router.replace(`/chat?id=${convId}`, { scroll: false }); } diff --git a/web/app/globals.css b/web/app/globals.css index fb521491..0ba62bfb 100644 --- a/web/app/globals.css +++ b/web/app/globals.css @@ -58,6 +58,8 @@ body { align-items: center; gap: 1.25rem; justify-content: center; + min-width: 0; + overflow: hidden; } /* Indivdual Link Styles */