Skip to content

feat: #237 - Add feedback button to patient results #239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: listOfMed
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 39 additions & 62 deletions frontend/src/components/Header/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ErrorMessage from "../ErrorMessage";
import ConversationList from "./ConversationList";
import { extractContentFromDOM } from "../../services/domExtraction";
import axios from "axios";
import { FaPlus, FaMinus, FaTimes, FaComment, FaComments, FaPills, FaLightbulb, FaArrowCircleDown } from "react-icons/fa";
import { FaPlus, FaMinus, FaTimes, FaComment, FaComments, FaPills, FaLightbulb, FaArrowCircleDown, FaExpandAlt, FaExpandArrowsAlt } from "react-icons/fa";
import {
fetchConversations,
continueConversation,
Expand Down Expand Up @@ -72,13 +72,6 @@ const Chat: React.FC<ChatDropDownProps> = ({ showChat, setShowChat }) => {
setPageContent(extractedContent);
}, []);

// useEffect(() => {
// if (chatContainerRef.current) {
// const chatContainer = chatContainerRef.current;
// chatContainer.scrollTop = chatContainer.scrollHeight;
// }
// }, [chatLog]);

const [bottom, setBottom] = useState(false);

const handleScroll = (event: React.UIEvent<HTMLElement>) => {
Expand All @@ -87,6 +80,8 @@ const Chat: React.FC<ChatDropDownProps> = ({ showChat, setShowChat }) => {
setBottom(bottom)
};

const [expandChat, setExpandChat] = useState(false);

useEffect(() => {
if (chatContainerRef.current && activeConversation) {
const chatContainer = chatContainerRef.current;
Expand Down Expand Up @@ -204,52 +199,6 @@ const Chat: React.FC<ChatDropDownProps> = ({ showChat, setShowChat }) => {
}
};

// const systemMessage = {
// role: "system",
// content: "You are a bot please keep conversation going.",
// };
// const sendMessage = (message: ChatLogItem[]) => {
// const baseUrl = import.meta.env.VITE_API_BASE_URL;
// const url = `${baseUrl}/chatgpt/chat`;

// const apiMessages = message.map((messageObject) => {
// let role = "";
// if (messageObject.is_user) {
// role = "user";
// } else {
// role = "assistant";
// }
// return { role: role, content: messageObject.content };
// });

// systemMessage.content += `If applicable, please use the following content to ask questions. If not applicable,
// please answer to the best of your ability: ${pageContent}`;

// const apiRequestBody = {
// prompt: [systemMessage, ...apiMessages],
// };

// setIsLoading(true);

// axios
// .post(url, apiRequestBody)
// .then((response) => {
// console.log(response);
// setChatLog((prevChatLog) => [
// ...prevChatLog,
// {
// is_user: false,
// content: response.data.message.choices[0].message.content,
// },
// ]);
// setIsLoading(false);
// })
// .catch((error) => {
// setIsLoading(false);
// console.log(error);
// });
// };

const handleSelectConversation = (id: Conversation["id"]) => {
const selectedConversation = conversations.find(
(conversation: any) => conversation.id === id,
Expand All @@ -267,13 +216,25 @@ const Chat: React.FC<ChatDropDownProps> = ({ showChat, setShowChat }) => {
};

useEffect(() => {
if (showChat) loadConversations();
if (showChat) {
loadConversations();

const resizeObserver = new ResizeObserver(() => {
const target = chatContainerRef.current;
if (target) {
const bottom = target.scrollHeight - Math.round(target.scrollTop) === target.clientHeight;
setBottom(bottom);
}
});
resizeObserver.observe(chatContainerRef.current);
return () => resizeObserver.disconnect(); // clean up
}
}, [showChat]);

return (
<>
{showChat ? (
<div className="show_chat ring-slate-1000/10 shadow">
<div className={`show_chat ring-slate-1000/10 shadow ${expandChat ? 'full-screen' : 'windowed'}`}>
<div
id="chat_container"
className=" mx-auto flex h-full flex-col overflow-auto rounded "
Expand Down Expand Up @@ -311,12 +272,28 @@ const Chat: React.FC<ChatDropDownProps> = ({ showChat, setShowChat }) => {
<br />
</div>

<button
className="delete flex items-center justify-center"
onClick={() => setShowChat(false)}
>
<FaTimes className="chat_icon" />
</button>
<div className="flex space-x-2">
<button
onClick={() =>
setExpandChat((prevState) => !prevState)
}
className="flex items-center justify-center"
>
{expandChat ? (
// Icon for "Shrink"
<FaExpandAlt className="chat_icon" />
) : (
// Icon for "expand"
<FaExpandArrowsAlt className="chat_icon" />
)}
</button>
<button
className="delete flex items-center justify-center"
onClick={() => setShowChat(false)}
>
<FaTimes className="chat_icon" />
</button>
</div>
</div>
<div id="inside_chat" onScroll={handleScroll} className="inside_chat" style={{scrollbarWidth: "thin", scrollBehavior: "smooth"}} ref={chatContainerRef}>
<button id="scroll_down" className="scroll_down animate-bounce" onClick={handleScrollDown} style={{ visibility: bottom ? 'hidden' : 'visible' }}>
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/components/Header/chat.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
}

.show_chat {
@apply fixed bottom-6 left-4 rounded h-[50%] w-[320px] rounded-lg bg-white border shadow-xl dark:bg-slate-800 dark:text-slate-300;
@apply fixed bottom-6 left-4 rounded rounded-lg bg-white border shadow-xl dark:bg-slate-800 dark:text-slate-300;
}

.show_chat.windowed {
@apply h-[50%] w-[320px];
}

.show_chat.full-screen {
@apply w-[95%] h-[95%];
}

.circle {
Expand Down
25 changes: 25 additions & 0 deletions frontend/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ReactNode } from "react";
import { FaTimes } from "react-icons/fa";

interface ModalProps {
isOpen: boolean;
onClose: React.MouseEventHandler<SVGElement>;
children: ReactNode;
}

function Modal ({ isOpen, onClose, children }: ModalProps) {
return (
<div className={`${isOpen ? 'fixed' : 'hidden'} inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50`}>
<div className="relative top-20 mx-auto p-5 border w-[90%] shadow-lg rounded-md bg-white">
<div className="flex justify-end hover:text-blue-500">
<FaTimes onClick={onClose} />
</div>
<div className="mt-3">
{children}
</div>
</div>
</div>
);
}

export default Modal;
13 changes: 9 additions & 4 deletions frontend/src/pages/Feedback/FeedbackForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export interface FormValues {
image: string;
}

interface FormProps {
id?: string;
}

// Error Message interface and validation
interface ErrorMessages {
[key: string]: string[];
Expand All @@ -27,7 +31,7 @@ const isValidErrorMessages = (data: unknown): data is ErrorMessages => {
);
};

const FeedbackForm = () => {
function FeedbackForm ({ id }: FormProps) {
const [feedback, setFeedback] = useState("");
const [errorMessages, setErrorMessages] = useState<ErrorMessages>({});
const [isPressed, setIsPressed] = useState(false);
Expand Down Expand Up @@ -194,10 +198,11 @@ const FeedbackForm = () => {

return (
<>
<div className="flex w-[100%] justify-between">
<div className="flex flex-col w-[100%] justify-between">
<h2 className="header_logo cursor-pointer font-satoshi text-xl font-bold text-gray-600 hover:text-blue-600 ">
Leave Us Feedback!
{ !id ? 'Leave Us Feedback!' : 'Report an Issue' }
</h2>
{ id && <h6 className="text-gray-500">Patient ID: <span className="font-light">{id}</span></h6> }
</div>
<section className="mx-auto w-full">
<form onSubmit={handleSubmit} className="mt-2">
Expand Down Expand Up @@ -421,7 +426,7 @@ const FeedbackForm = () => {
className="btnGray mr-5"
onClick={handleCancel}
>
Cancel
Clear
</button>
</div>
<button
Expand Down
Loading