|
|
@@ -5,7 +5,11 @@ import { Message, ChatState, ChatResponse, SuggestedPrompt, MedicalAlert } from
|
|
|
|
|
|
export const MAX_MESSAGES = 5;
|
|
|
|
|
|
-export const useChat = () => {
|
|
|
+interface UseChatProps {
|
|
|
+ chatType: "medical" | "psychological";
|
|
|
+}
|
|
|
+
|
|
|
+export const useChat = ({ chatType }: UseChatProps) => {
|
|
|
const [messages, setMessages] = useState<Message[]>([]);
|
|
|
const [messageCount, setMessageCount] = useState(0);
|
|
|
const [isLimitReached, setIsLimitReached] = useState(false);
|
|
|
@@ -22,13 +26,17 @@ export const useChat = () => {
|
|
|
const [medicalAlertDetected, setMedicalAlertDetected] = useState<MedicalAlert | null>(null);
|
|
|
const [isSchedulingFromAlert, setIsSchedulingFromAlert] = useState(false);
|
|
|
const [showMedicalAlertBanner, setShowMedicalAlertBanner] = useState(false);
|
|
|
+ const [crisisDetected, setCrisisDetected] = useState(false);
|
|
|
+ const [showCrisisBanner, setShowCrisisBanner] = useState(false);
|
|
|
|
|
|
- const remainingMessages = Math.max(0, MAX_MESSAGES - messageCount);
|
|
|
- const isLastMessage = remainingMessages === 1;
|
|
|
+ const isPsychological = chatType === "psychological";
|
|
|
+ const remainingMessages = isPsychological ? Infinity : Math.max(0, MAX_MESSAGES - messageCount);
|
|
|
+ const isLastMessage = !isPsychological && remainingMessages === 1;
|
|
|
|
|
|
// Cargar estado desde localStorage al iniciar
|
|
|
useEffect(() => {
|
|
|
- const savedState = localStorage.getItem("chatState");
|
|
|
+ const storageKey = `chatState_${chatType}`;
|
|
|
+ const savedState = localStorage.getItem(storageKey);
|
|
|
if (savedState) {
|
|
|
try {
|
|
|
const parsed: ChatState = JSON.parse(savedState);
|
|
|
@@ -61,10 +69,11 @@ export const useChat = () => {
|
|
|
setShowSuggestions(true);
|
|
|
}
|
|
|
}
|
|
|
- }, []);
|
|
|
+ }, [chatType]);
|
|
|
|
|
|
// Guardar estado en localStorage cuando cambie
|
|
|
useEffect(() => {
|
|
|
+ const storageKey = `chatState_${chatType}`;
|
|
|
const stateToSave: ChatState = {
|
|
|
messages,
|
|
|
messageCount,
|
|
|
@@ -72,8 +81,8 @@ export const useChat = () => {
|
|
|
reportGenerated,
|
|
|
currentSuggestions,
|
|
|
};
|
|
|
- localStorage.setItem("chatState", JSON.stringify(stateToSave));
|
|
|
- }, [messages, messageCount, isLimitReached, reportGenerated, currentSuggestions]);
|
|
|
+ localStorage.setItem(storageKey, JSON.stringify(stateToSave));
|
|
|
+ }, [messages, messageCount, isLimitReached, reportGenerated, currentSuggestions, chatType]);
|
|
|
|
|
|
// Función para generar reporte usando useCallback para evitar re-renderizados
|
|
|
const generateMedicalReport = useCallback(async () => {
|
|
|
@@ -99,6 +108,7 @@ export const useChat = () => {
|
|
|
body: JSON.stringify({
|
|
|
content: report,
|
|
|
messages: messages,
|
|
|
+ chatType,
|
|
|
}),
|
|
|
});
|
|
|
|
|
|
@@ -115,9 +125,10 @@ export const useChat = () => {
|
|
|
}
|
|
|
}, [messages, isGeneratingReport, reportGenerated]);
|
|
|
|
|
|
- // Efecto para generar reporte cuando se alcanza el límite
|
|
|
+ // Efecto para generar reporte cuando se alcanza el límite (solo para chat médico)
|
|
|
useEffect(() => {
|
|
|
if (
|
|
|
+ !isPsychological &&
|
|
|
messageCount >= MAX_MESSAGES &&
|
|
|
!isLimitReached &&
|
|
|
!reportGenerated &&
|
|
|
@@ -137,6 +148,7 @@ export const useChat = () => {
|
|
|
}
|
|
|
}
|
|
|
}, [
|
|
|
+ isPsychological,
|
|
|
messageCount,
|
|
|
isLimitReached,
|
|
|
reportGenerated,
|
|
|
@@ -179,6 +191,7 @@ export const useChat = () => {
|
|
|
body: JSON.stringify({
|
|
|
message: messageToSend,
|
|
|
messages: [...messages, userMessage],
|
|
|
+ chatType,
|
|
|
}),
|
|
|
});
|
|
|
|
|
|
@@ -205,7 +218,7 @@ export const useChat = () => {
|
|
|
const decoder = new TextDecoder();
|
|
|
let buffer = "";
|
|
|
let fullContent = "";
|
|
|
- let metadata: { medicalAlert?: string; suggestions?: SuggestedPrompt[] } = {};
|
|
|
+ let metadata: { medicalAlert?: string; suggestions?: SuggestedPrompt[]; crisisDetected?: boolean } = {};
|
|
|
|
|
|
if (!reader) {
|
|
|
throw new Error("No se pudo obtener el reader del stream");
|
|
|
@@ -253,7 +266,8 @@ export const useChat = () => {
|
|
|
// Guardar metadatos
|
|
|
metadata = {
|
|
|
medicalAlert: parsed.medicalAlert,
|
|
|
- suggestions: parsed.suggestions
|
|
|
+ suggestions: parsed.suggestions,
|
|
|
+ crisisDetected: parsed.crisisDetected
|
|
|
};
|
|
|
console.log("📦 [CHAT] Metadatos recibidos:", metadata);
|
|
|
}
|
|
|
@@ -270,6 +284,13 @@ export const useChat = () => {
|
|
|
const totalTime = Date.now() - startTime;
|
|
|
console.log("✅ [CHAT] Respuesta completa procesada en:", totalTime, "ms");
|
|
|
|
|
|
+ // Detectar crisis en chat psicológico
|
|
|
+ if (isPsychological && metadata.crisisDetected) {
|
|
|
+ console.log("🚨 [CHAT] Crisis detectada en chat psicológico");
|
|
|
+ setCrisisDetected(true);
|
|
|
+ setShowCrisisBanner(true);
|
|
|
+ }
|
|
|
+
|
|
|
// Detectar alerta médica
|
|
|
if (metadata.medicalAlert && metadata.medicalAlert !== "NO_AGENDAR" && !medicalAlertDetected) {
|
|
|
console.log("🚨 [CHAT] Alerta médica detectada:", metadata.medicalAlert);
|
|
|
@@ -292,7 +313,8 @@ export const useChat = () => {
|
|
|
);
|
|
|
|
|
|
// Mostrar sugerencias dinámicas después del streaming si no es el último mensaje
|
|
|
- if (messageCount + 1 < MAX_MESSAGES && metadata.suggestions) {
|
|
|
+ // En chat psicológico no mostrar sugerencias dinámicas
|
|
|
+ if (!isPsychological && messageCount + 1 < MAX_MESSAGES && metadata.suggestions) {
|
|
|
setCurrentSuggestions(metadata.suggestions);
|
|
|
setShowDynamicSuggestions(true);
|
|
|
setInputDisabledForSuggestions(true);
|
|
|
@@ -334,7 +356,8 @@ export const useChat = () => {
|
|
|
setMessages((prev) => [...prev, fallbackMessage]);
|
|
|
|
|
|
// Mostrar sugerencias dinámicas si no es el último mensaje
|
|
|
- if (messageCount + 1 < MAX_MESSAGES) {
|
|
|
+ // En chat psicológico no mostrar sugerencias dinámicas
|
|
|
+ if (!isPsychological && messageCount + 1 < MAX_MESSAGES) {
|
|
|
setCurrentSuggestions(fallbackMessage.suggestions || []);
|
|
|
setShowDynamicSuggestions(true);
|
|
|
setInputDisabledForSuggestions(true);
|
|
|
@@ -383,7 +406,8 @@ export const useChat = () => {
|
|
|
setMessages((prev) => [...prev, fallbackMessage]);
|
|
|
|
|
|
// Mostrar sugerencias dinámicas si no es el último mensaje
|
|
|
- if (messageCount + 1 < MAX_MESSAGES) {
|
|
|
+ // En chat psicológico no mostrar sugerencias dinámicas
|
|
|
+ if (!isPsychological && messageCount + 1 < MAX_MESSAGES) {
|
|
|
setCurrentSuggestions(fallbackMessage.suggestions || []);
|
|
|
setShowDynamicSuggestions(true);
|
|
|
setInputDisabledForSuggestions(true);
|
|
|
@@ -416,8 +440,11 @@ export const useChat = () => {
|
|
|
setMedicalAlertDetected(null);
|
|
|
setShowMedicalAlertBanner(false);
|
|
|
setIsSchedulingFromAlert(false);
|
|
|
+ setCrisisDetected(false);
|
|
|
+ setShowCrisisBanner(false);
|
|
|
// Limpiar localStorage
|
|
|
- localStorage.removeItem("chatState");
|
|
|
+ const storageKey = `chatState_${chatType}`;
|
|
|
+ localStorage.removeItem(storageKey);
|
|
|
notifications.chat.newConsultation();
|
|
|
};
|
|
|
|
|
|
@@ -501,6 +528,10 @@ export const useChat = () => {
|
|
|
setShowMedicalAlertBanner(false);
|
|
|
};
|
|
|
|
|
|
+ const dismissCrisisBanner = () => {
|
|
|
+ setShowCrisisBanner(false);
|
|
|
+ };
|
|
|
+
|
|
|
return {
|
|
|
messages,
|
|
|
messageCount,
|
|
|
@@ -530,5 +561,8 @@ export const useChat = () => {
|
|
|
isSchedulingFromAlert,
|
|
|
handleScheduleFromAlert,
|
|
|
dismissMedicalAlertBanner,
|
|
|
+ crisisDetected,
|
|
|
+ showCrisisBanner,
|
|
|
+ dismissCrisisBanner,
|
|
|
};
|
|
|
-};
|
|
|
+};;
|