Mobile UI for ai chat, fixed backend issue

This commit is contained in:
augmentedpotato
2026-04-19 08:25:14 -06:00
parent ba1ccf9d95
commit fe0b00bcd1
2 changed files with 22 additions and 12 deletions

View File

@@ -53,7 +53,7 @@ public interface AppointmentRepository extends JpaRepository<Appointment, Long>
List<Appointment> findByPet_Id(Long petId); List<Appointment> 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')") @Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.pet.id = :petId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')")
List<Appointment> findByPetIdAndAppointmentDate(@Param("petId") Long petId, @Param("date") LocalDate date); List<Appointment> findByPetIdAndAppointmentDate(@Param("petId") Long petId, @Param("date") LocalDate date);
List<Appointment> findByAppointmentDateAndAppointmentStatusIgnoreCase(LocalDate date, String status); List<Appointment> findByAppointmentDateAndAppointmentStatusIgnoreCase(LocalDate date, String status);

View File

@@ -68,11 +68,23 @@ function AttachmentPreview({ url, name, token }) {
); );
} }
function useIsMobile() {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const check = () => setIsMobile(window.innerWidth < 640);
check();
window.addEventListener("resize", check);
return () => window.removeEventListener("resize", check);
}, []);
return isMobile;
}
function AiChatPage() { function AiChatPage() {
const { user, token, loading: authLoading } = useAuth(); const { user, token, loading: authLoading } = useAuth();
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const conversationIdParam = searchParams.get("id"); const conversationIdParam = searchParams.get("id");
const isMobile = useIsMobile();
const [conversation, setConversation] = useState(null); const [conversation, setConversation] = useState(null);
const [messages, setMessages] = useState([]); const [messages, setMessages] = useState([]);
@@ -496,8 +508,8 @@ function AiChatPage() {
</section> </section>
<section style={s.chatSection}> <section style={s.chatSection}>
<div style={{ display: "flex", gap: "1rem", alignItems: "flex-start" }}> <div style={{ display: "flex", flexDirection: isMobile ? "column" : "row", gap: "1rem", alignItems: "flex-start" }}>
<div style={s.sidebar}> <div style={{ ...s.sidebar, width: isMobile ? "100%" : 230, maxHeight: isMobile ? 260 : "calc(100vh - 220px)" }}>
<div style={s.sidebarHeader}> <div style={s.sidebarHeader}>
<span style={s.sidebarTitle}>All Conversations</span> <span style={s.sidebarTitle}>All Conversations</span>
</div> </div>
@@ -552,7 +564,7 @@ function AiChatPage() {
</button> </button>
</div> </div>
<div style={{ flex: 1, minWidth: 0 }}> <div style={{ flex: 1, minWidth: 0, width: isMobile ? "100%" : undefined }}>
{!conversation ? ( {!conversation ? (
<div style={s.noConvCard}> <div style={s.noConvCard}>
<div style={s.noConvIcon}>🐾</div> <div style={s.noConvIcon}>🐾</div>
@@ -568,7 +580,7 @@ function AiChatPage() {
</div> </div>
) : ( ) : (
<div style={s.chatCard}> <div style={s.chatCard}>
<div style={s.chatHeader}> <div style={{ ...s.chatHeader, flexDirection: isMobile ? "column" : "row", alignItems: isMobile ? "flex-start" : "center", gap: isMobile ? "0.6rem" : 0 }}>
<div style={s.chatHeaderLeft}> <div style={s.chatHeaderLeft}>
<div style={isEscalated ? s.agentAvatar : s.aiAvatar}>{isEscalated ? "👤" : "🐾"}</div> <div style={isEscalated ? s.agentAvatar : s.aiAvatar}>{isEscalated ? "👤" : "🐾"}</div>
<div> <div>
@@ -581,14 +593,14 @@ function AiChatPage() {
</div> </div>
</div> </div>
</div> </div>
<div style={{ display: "flex", gap: "0.5rem" }}> <div style={{ display: "flex", gap: "0.5rem", width: isMobile ? "100%" : undefined }}>
{!isEscalated && !isClosed && ( {!isEscalated && !isClosed && (
<button style={s.humanBtn} onClick={handleSwitchToHuman} title="Connect with a human support agent"> <button style={{ ...s.humanBtn, flex: isMobile ? 1 : undefined, fontSize: isMobile ? "0.75rem" : undefined, padding: isMobile ? "0.4rem 0.6rem" : undefined }} onClick={handleSwitchToHuman} title="Connect with a human support agent">
Chat with a Real Person Chat with a Real Person
</button> </button>
)} )}
{!isClosed && ( {!isClosed && (
<button style={s.closeConvBtn} onClick={handleCloseConversation} title="Close this conversation"> <button style={{ ...s.closeConvBtn, flex: isMobile ? 1 : undefined, fontSize: isMobile ? "0.75rem" : undefined, padding: isMobile ? "0.4rem 0.6rem" : undefined }} onClick={handleCloseConversation} title="Close this conversation">
Close Chat Close Chat
</button> </button>
)} )}
@@ -790,7 +802,6 @@ const s = {
padding: "1.5rem 1rem 2rem", padding: "1.5rem 1rem 2rem",
}, },
sidebar: { sidebar: {
width: 230,
flexShrink: 0, flexShrink: 0,
background: "white", background: "white",
borderRadius: 16, borderRadius: 16,
@@ -798,8 +809,7 @@ const s = {
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
overflow: "hidden", overflow: "hidden",
maxHeight: "calc(100vh - 220px)", minHeight: 200,
minHeight: 300,
}, },
sidebarHeader: { sidebarHeader: {
display: "flex", display: "flex",
@@ -899,7 +909,7 @@ const s = {
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
height: "calc(100vh - 220px)", height: "calc(100vh - 220px)",
minHeight: 450, minHeight: 400,
}, },
chatHeader: { chatHeader: {
display: "flex", display: "flex",