diff --git a/sanitas_backend/src/handlers/GetGynecoObstetricHistory/get-gynecoobstetric-history-patient.integration.test.mjs b/sanitas_backend/src/handlers/GetGynecoObstetricHistory/get-gynecoobstetric-history-patient.integration.test.mjs
index 7c4ab932..5babf713 100644
--- a/sanitas_backend/src/handlers/GetGynecoObstetricHistory/get-gynecoobstetric-history-patient.integration.test.mjs
+++ b/sanitas_backend/src/handlers/GetGynecoObstetricHistory/get-gynecoobstetric-history-patient.integration.test.mjs
@@ -56,6 +56,7 @@ async function createPatientWithGynecologicalHistory() {
otherCondition: [
{
medication: {
+ illness: "illness A",
medication: "Med D",
dosage: "500mg",
frequency: "Once a day",
diff --git a/sanitas_backend/src/handlers/UpdateGynecoObstetricHistory/update-gynecoobstetric-history-patient.integration.test.mjs b/sanitas_backend/src/handlers/UpdateGynecoObstetricHistory/update-gynecoobstetric-history-patient.integration.test.mjs
index 91419156..4abc1538 100644
--- a/sanitas_backend/src/handlers/UpdateGynecoObstetricHistory/update-gynecoobstetric-history-patient.integration.test.mjs
+++ b/sanitas_backend/src/handlers/UpdateGynecoObstetricHistory/update-gynecoobstetric-history-patient.integration.test.mjs
@@ -59,6 +59,7 @@ function generateValidUpdate(patientId) {
otherCondition: [
{
medication: {
+ illness: "illness A",
medication: "Med D",
dosage: "500mg",
frequency: "Once a day",
@@ -150,6 +151,7 @@ describe("Update Gynecological Medical History integration tests", () => {
otherCondition: [
{
medication: {
+ illness: "illness A",
medication: "Med D",
dosage: "500mg",
frequency: "Once a day",
diff --git a/sanitas_frontend/src/components/DashboardSidebar/index.jsx b/sanitas_frontend/src/components/DashboardSidebar/index.jsx
index 554f8881..bdc140f9 100644
--- a/sanitas_frontend/src/components/DashboardSidebar/index.jsx
+++ b/sanitas_frontend/src/components/DashboardSidebar/index.jsx
@@ -166,7 +166,7 @@ export default function DashboardSidebar({
fontWeight: "normal",
paddingBottom: "1rem",
paddingTop: "1rem",
- borderBottom: `0.1rem solid ${colors.darkerGrey}`,
+ borderBottom: `0.04rem solid ${colors.darkerGrey}`,
}}
>
Antecedentes
diff --git a/sanitas_frontend/src/components/DropdownMenu/index.jsx b/sanitas_frontend/src/components/DropdownMenu/index.jsx
index 372777a0..c8c9b078 100644
--- a/sanitas_frontend/src/components/DropdownMenu/index.jsx
+++ b/sanitas_frontend/src/components/DropdownMenu/index.jsx
@@ -75,7 +75,7 @@ export default function DropdownMenu({
indicator: {
position: "absolute",
top: "50%",
- right: "5%",
+ right: "6%",
transform: `translateY(-50%) rotate(${isOpen ? "180deg" : "0deg"})`,
transition: "transform 0.3s",
pointerEvents: "none",
diff --git a/sanitas_frontend/src/dataLayer.mjs b/sanitas_frontend/src/dataLayer.mjs
index c49d3210..f624f680 100644
--- a/sanitas_frontend/src/dataLayer.mjs
+++ b/sanitas_frontend/src/dataLayer.mjs
@@ -1179,6 +1179,75 @@ export const updatePsichiatricHistory = async (
}
};
+export const getGynecologicalHistory = async (patientId) => {
+ const sessionResponse = IS_PRODUCTION
+ ? await getSession()
+ : await mockGetSession(true);
+ if (sessionResponse.error) {
+ return { error: sessionResponse.error };
+ }
+
+ if (!sessionResponse.result.isValid()) {
+ return { error: "Invalid session!" };
+ }
+
+ const token = sessionResponse?.result?.idToken?.jwtToken ?? "no-token";
+ const url = `${PROTECTED_URL}/patient/gyneco-history/${patientId}`;
+
+ try {
+ const response = await axios.get(url, {
+ headers: { Authorization: token },
+ });
+ if (response.status === 200) {
+ return { result: response.data };
+ }
+ } catch (error) {
+ if (error.response) {
+ return { error: error.response.data };
+ }
+ return { error: error.message };
+ }
+};
+
+export const updateGynecologicalHistory = async (
+ patientId,
+ gynecologicalHistoryDetails,
+) => {
+ const sessionResponse = IS_PRODUCTION
+ ? await getSession()
+ : await mockGetSession(true);
+ if (sessionResponse.error) {
+ return { error: sessionResponse.error };
+ }
+
+ if (!sessionResponse.result.isValid()) {
+ return { error: "Invalid session!" };
+ }
+
+ const token = sessionResponse?.result?.idToken?.jwtToken ?? "no-token";
+ const url = `${PROTECTED_URL}/patient/gyneco-history`;
+
+ const payload = {
+ patientId: patientId,
+ medicalHistory: gynecologicalHistoryDetails,
+ };
+
+ try {
+ const response = await axios.put(url, payload, {
+ headers: { Authorization: token },
+ });
+ if (response.status === 200) {
+ return { result: response.data };
+ }
+ return { error: `Unexpected status code: ${response.status}` };
+ } catch (error) {
+ if (error.response) {
+ return { error: error.response.data };
+ }
+ return { error: error.message };
+ }
+};
+
/**
* @callback LinkAccountToPatientCallback
* @param {string} cui
diff --git a/sanitas_frontend/src/router.jsx b/sanitas_frontend/src/router.jsx
index 088b1656..be6103ef 100644
--- a/sanitas_frontend/src/router.jsx
+++ b/sanitas_frontend/src/router.jsx
@@ -21,6 +21,8 @@ import {
getStudentPatientInformation,
getSurgicalHistory,
getTraumatologicalHistory,
+ getAllergicHistory,
+ getGynecologicalHistory,
searchPatient,
submitPatientData,
updateCollaboratorInformation,
@@ -32,8 +34,8 @@ import {
updateSurgicalHistory,
updateStudentSurgicalHistory,
updateTraumatologicalHistory,
- getAllergicHistory,
updateAllergicHistory,
+ updateGynecologicalHistory,
getPsichiatricHistory,
updatePsichiatricHistory,
getRole,
@@ -53,6 +55,7 @@ import SearchPatientView from "./views/SearchPatientView";
import UpdateInfoView from "./views/UpdateGeneralInformationView";
import { TraumatologicHistory } from "./views/History/Traumatological";
import { AllergicHistory } from "./views/History/Allergic";
+import { ObGynHistory } from "./views/History/ObGyn";
import { PsichiatricHistory } from "./views/History/Psichiatric";
import StudentWelcomeView from "./views/StudentWelcomeView";
import { LinkPatientView } from "./views/LinkPatientView";
@@ -80,6 +83,7 @@ export const UPDATE_PATIENT_NAV_PATHS = {
PERSONAL_HISTORY: "personal",
NONPATHOLOGICAL_HISTORY: "non-pathological",
ALLERGIC_HISTORY: "allergic",
+ OBGYN_HISTORY: "obgyn",
PSICHIATRIC_HISTORY: "psichiatric",
// TODO: Add other Navigation routes...
};
@@ -132,6 +136,11 @@ export const DEFAULT_DASHBOARD_SIDEBAR_PROPS = {
`${NAV_PATHS.UPDATE_PATIENT}/${UPDATE_PATIENT_NAV_PATHS.ALLERGIC_HISTORY}`,
);
},
+ navigateToObstetrics: (navigate) => {
+ navigate(
+ `${NAV_PATHS.UPDATE_PATIENT}/${UPDATE_PATIENT_NAV_PATHS.OBGYN_HISTORY}`,
+ );
+ },
navigateToPsiquiatric: (navigate) => {
navigate(
`${NAV_PATHS.UPDATE_PATIENT}/${UPDATE_PATIENT_NAV_PATHS.PSICHIATRIC_HISTORY}`,
@@ -275,6 +284,21 @@ const psichiatricHistoryView = (
);
+const obgynHistoryView = (
+
+
+
+);
+
export const ROUTES = [
{
path: NAV_PATHS.SEARCH_PATIENT,
@@ -374,6 +398,10 @@ export const ROUTES = [
path: UPDATE_PATIENT_NAV_PATHS.ALLERGIC_HISTORY,
element: allergicHistoryView,
},
+ {
+ path: UPDATE_PATIENT_NAV_PATHS.OBGYN_HISTORY,
+ element: obgynHistoryView,
+ },
{
path: UPDATE_PATIENT_NAV_PATHS.PSICHIATRIC_HISTORY,
element: psichiatricHistoryView,
diff --git a/sanitas_frontend/src/views/History/ObGyn/index.jsx b/sanitas_frontend/src/views/History/ObGyn/index.jsx
new file mode 100644
index 00000000..f173ef69
--- /dev/null
+++ b/sanitas_frontend/src/views/History/ObGyn/index.jsx
@@ -0,0 +1,1714 @@
+import { Suspense, useEffect, useState, useMemo } from "react";
+import "react-toastify/dist/ReactToastify.css";
+import { toast } from "react-toastify";
+import BaseButton from "src/components/Button/Base/index";
+import DashboardSidebar from "src/components/DashboardSidebar";
+import DropdownMenu from "src/components/DropdownMenu";
+import { BaseInput } from "src/components/Input/index";
+import { RadioInput } from "src/components/Input/index";
+import Throbber from "src/components/Throbber";
+import { colors, fonts, fontSize } from "src/theme.mjs";
+import WrapPromise from "src/utils/promiseWrapper";
+import { useRef } from "react";
+import CheckIcon from "@tabler/icons/outline/check.svg";
+import EditIcon from "@tabler/icons/outline/edit.svg";
+import CancelIcon from "@tabler/icons/outline/x.svg";
+import IconButton from "src/components/Button/Icon";
+
+export function ObGynHistory({
+ getBirthdayPatientInfo,
+ getObGynHistory,
+ updateObGynHistory,
+ sidebarConfig,
+ useStore,
+}) {
+ const id = useStore((s) => s.selectedPatientId);
+ const [reload, setReload] = useState(false); // Controls reload toggling for refetching data
+
+ const LoadingView = () => {
+ return (
+
+ );
+ };
+
+ // biome-ignore lint/correctness/useExhaustiveDependencies: Reload the page
+ const birthdayResource = useMemo(
+ () => WrapPromise(getBirthdayPatientInfo(id)),
+ [id, reload, getBirthdayPatientInfo],
+ );
+ // biome-ignore lint/correctness/useExhaustiveDependencies: Reload the page
+ const obgynHistoryResource = useMemo(
+ () => WrapPromise(getObGynHistory(id)),
+ [id, reload, getObGynHistory],
+ );
+
+ // Triggers a state change to force reloading of data
+ const triggerReload = () => {
+ setReload((prev) => !prev);
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ Antecedentes Ginecoobstétricos
+
+
+ Registro de antecedentes ginecoobstétricos
+
+
+
+
+ }>
+
+
+
+
+
+
+ );
+}
+
+function DiagnosisSection({
+ title,
+ diagnosisKey,
+ editable,
+ isNew,
+ isFirstTime,
+ onCancel,
+ diagnosisDetails,
+ handleDiagnosedChange,
+}) {
+ const [diagnosed, setDiagnosed] = useState(!!diagnosisDetails.medication);
+ const [diagnosisName, setDiagnosisName] = useState(
+ diagnosisDetails.illness || "",
+ );
+ const [medication, setMedication] = useState(
+ diagnosisDetails.medication || "",
+ );
+ const [dose, setDose] = useState(diagnosisDetails.dosage || "");
+ const [frequency, setFrequency] = useState(diagnosisDetails.frequency || "");
+
+ const showFields = isNew || diagnosed;
+
+ const handleDiagnosedChangeRef = useRef(handleDiagnosedChange);
+ handleDiagnosedChangeRef.current = handleDiagnosedChange;
+
+ useEffect(() => {
+ const stableHandleDiagnosedChange = handleDiagnosedChangeRef.current;
+ stableHandleDiagnosedChange(diagnosisKey, true, {
+ illness: diagnosisName,
+ medication: medication,
+ dosage: dose,
+ frequency: frequency,
+ });
+ }, [diagnosisName, medication, dose, frequency, diagnosisKey]);
+
+ return (
+
+
+ {title}
+
+ {!isNew && (
+
+ {
+ const newState = !diagnosed;
+ setDiagnosed(newState);
+ handleDiagnosedChange(diagnosisKey, newState, {
+ medication: medication,
+ dosage: dose,
+ frequency: frequency,
+ });
+ }}
+ label="Sí"
+ disabled={editable}
+ />
+ {
+ setDiagnosed(false);
+ handleDiagnosedChange(diagnosisKey, false);
+ setDiagnosisName("");
+ setMedication("");
+ setDose("");
+ setFrequency("");
+ }}
+ label="No"
+ disabled={editable}
+ />
+
+ )}
+ {showFields && (
+ <>
+ {isNew && (
+
+
+ Nombre del diagnóstico:
+
+
+
setDiagnosisName(e.target.value)}
+ readOnly={editable}
+ placeholder="Ingrese el nombre del diagnóstico."
+ style={{
+ width: "60%",
+ height: "3rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+ )}
+
+
+ Medicamento:
+
+
+
setMedication(e.target.value)}
+ readOnly={editable}
+ placeholder="Ingrese el medicamento administrado."
+ style={{
+ width: "60%",
+ height: "3rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+ Dosis:
+
+ setDose(e.target.value)}
+ readOnly={editable}
+ placeholder="Ingrese cuánto. Ej. 50mg (Este campo es opcional)"
+ style={{
+ width: "60%",
+ height: "3rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+
+ Frecuencia:
+
+
+ setFrequency(e.target.value)}
+ readOnly={editable}
+ placeholder="Ingrese cada cuándo administra el medicamento (Ej. Cada dos días, cada 12 horas...)"
+ style={{
+ width: "60%",
+ height: "3rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+ {(isFirstTime || editable) && isNew && (
+
+ )}
+ >
+ )}
+
+ );
+}
+
+function OperationSection({
+ title,
+ operationKey,
+ editable,
+ isFirstTime,
+ operationDetailsResource,
+ updateGlobalOperations,
+ handlePerformedChange,
+ birthdayResource,
+}) {
+ const checkPerformed = (resource) => {
+ if (Array.isArray(resource)) {
+ return resource.length > 0;
+ }
+ if (typeof resource === "object" && resource !== null) {
+ return Object.keys(resource).length > 0 && resource.year !== null;
+ }
+ return !!resource;
+ };
+
+ const [performed, setPerformed] = useState(() =>
+ checkPerformed(operationDetailsResource),
+ );
+ const isArray = Array.isArray(operationDetailsResource);
+ const [operationDetails, setOperationDetails] = useState(() =>
+ isArray ? operationDetailsResource : [operationDetailsResource],
+ );
+
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Ignoring complexity for this function
+ const handlePerformedChangeInternal = (newPerformedStatus) => {
+ setPerformed(newPerformedStatus);
+ handlePerformedChange(operationKey, newPerformedStatus);
+
+ if (!newPerformedStatus) {
+ const clearedDetails = isArray ? [] : {};
+ setOperationDetails(clearedDetails);
+ updateGlobalOperations(operationKey, clearedDetails);
+ } else {
+ if (isArray && (!operationDetails || operationDetails.length === 0)) {
+ const defaultDetail = { year: "", complications: false };
+ const newDetails = [defaultDetail];
+ setOperationDetails(newDetails);
+ updateGlobalOperations(operationKey, newDetails);
+ } else if (
+ !isArray &&
+ (!operationDetails || Object.keys(operationDetails).length === 0)
+ ) {
+ const defaultDetail = { year: "", complications: false };
+ setOperationDetails([defaultDetail]);
+ updateGlobalOperations(operationKey, [defaultDetail]);
+ }
+ }
+ };
+
+ const addOperationDetail = () => {
+ if (!canAddMore()) return;
+ const newDetail = { year: null, complications: false };
+ const newDetails = [...operationDetails, newDetail];
+ setOperationDetails(newDetails);
+ updateGlobalOperations(operationKey, newDetails);
+ };
+
+ const canAddMore = () => {
+ if (
+ operationKey === "breastMassResection" ||
+ operationKey === "ovarianCysts"
+ ) {
+ if (operationKey === "breastMassResection") {
+ return operationDetails.length < 2;
+ }
+ return true;
+ }
+ return false;
+ };
+
+ const handleComplicationChange = (index, value) => {
+ const updatedDetails = [...operationDetails];
+ updatedDetails[index].complications = value;
+ setOperationDetails(updatedDetails);
+ updateGlobalOperations(operationKey, updatedDetails);
+ };
+
+ const removeOperationDetail = (index) => {
+ if (operationDetails.length > 1) {
+ const newDetails = operationDetails.filter((_, idx) => idx !== index);
+ setOperationDetails(newDetails);
+ updateGlobalOperations(operationKey, newDetails);
+ }
+ };
+
+ const [yearOptions, setYearOptions] = useState([]);
+
+ const birthYearResult = birthdayResource.read();
+
+ const birthYearData = birthYearResult.result;
+ const currentYear = new Date().getFullYear();
+ const birthYear = birthYearData?.birthdate
+ ? new Date(birthYearData.birthdate).getUTCFullYear()
+ : null;
+
+ useEffect(() => {
+ if (birthYear) {
+ const options = [];
+ for (let year = birthYear; year <= currentYear; year++) {
+ options.push({ value: year, label: year.toString() });
+ }
+ setYearOptions(options);
+ }
+ }, [birthYear, currentYear]);
+
+ const handleYearChange = (index, year) => {
+ const updatedDetails = [...operationDetails];
+ updatedDetails[index].year = year || "";
+ setOperationDetails(updatedDetails);
+ updateGlobalOperations(operationKey, updatedDetails);
+ };
+
+ return (
+
+
+ {title}
+
+
+ handlePerformedChangeInternal(true)}
+ label="Sí"
+ disabled={editable}
+ />
+ handlePerformedChangeInternal(false)}
+ label="No"
+ disabled={editable}
+ />
+
+ {performed &&
+ Array.isArray(operationDetails) &&
+ operationDetails.map((detail, index) => (
+ // biome-ignore lint/suspicious/noArrayIndexKey: The index is used to identify the operation details
+
+ {index !== 0 && (
+
+ )}
+
+
+ ¿En qué año?
+
+
handleYearChange(index, e.target.value)}
+ style={{
+ container: {
+ width: "60%",
+ height: "10%",
+ paddingLeft: "0.5rem",
+ },
+ select: {},
+ option: {},
+ indicator: {
+ top: "48%",
+ right: "4%",
+ },
+ }}
+ />
+
+
+ ¿Tuvo alguna complicación?:
+
+
+ handleComplicationChange(index, true)}
+ label="Sí"
+ disabled={editable}
+ />
+ handleComplicationChange(index, false)}
+ label="No"
+ disabled={editable}
+ />
+
+ {index !== 0 && (isFirstTime || !editable) ? (
+
+ removeOperationDetail(index)}
+ style={{
+ width: "25%",
+ height: "3rem",
+ backgroundColor: "#fff",
+ color: colors.primaryBackground,
+ border: `1.5px solid ${colors.primaryBackground}`,
+ }}
+ />
+
+ ) : null}
+
+ ))}
+
+ {performed && canAddMore() && (
+
+ {(isFirstTime || !editable) && (
+
+ )}
+
+ )}
+
+ );
+}
+
+// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Ignoring complexity for this function
+function ObGynView({
+ id,
+ birthdayResource,
+ obgynHistoryResource,
+ updateObGynHistory,
+ triggerReload,
+}) {
+ const gynecologicalHistoryResult = obgynHistoryResource.read();
+
+ let errorMessage = "";
+ if (gynecologicalHistoryResult.error) {
+ const error = gynecologicalHistoryResult.error;
+ if (error?.response) {
+ const { status } = error.response;
+ errorMessage =
+ status < 500
+ ? "Ha ocurrido un error en la búsqueda, ¡Por favor vuelve a intentarlo!"
+ : "Ha ocurrido un error interno, lo sentimos.";
+ } else {
+ errorMessage =
+ "Ha ocurrido un error procesando tu solicitud, por favor vuelve a intentarlo.";
+ }
+ }
+
+ const {
+ firstMenstrualPeriod = { data: { age: null } },
+ regularCycles = { data: { isRegular: null } },
+ painfulMenstruation = { data: { isPainful: null, medication: "" } },
+ pregnancies = {
+ data: {
+ totalPregnancies: null,
+ abortions: null,
+ cesareanSections: null,
+ vaginalDeliveries: null,
+ },
+ },
+ diagnosedIllnesses = {
+ data: {
+ ovarianCysts: {
+ medication: { dosage: "", frequency: "", medication: "" },
+ },
+ uterineMyomatosis: {
+ medication: { dosage: "", frequency: "", medication: "" },
+ },
+ endometriosis: {
+ medication: { dosage: "", frequency: "", medication: "" },
+ },
+ otherCondition: {
+ medication: {
+ dosage: "",
+ frequency: "",
+ medication: "",
+ illness: "",
+ },
+ },
+ },
+ },
+ hasSurgeries = {
+ data: {
+ ovarianCystsSurgery: [{ year: null, complications: false }],
+ hysterectomy: { year: null, complications: false },
+ sterilizationSurgery: { year: null, complications: false },
+ breastResection: [{ year: null, complications: false }],
+ },
+ },
+ } = gynecologicalHistoryResult.result?.medicalHistory || {};
+
+ const [age, setAge] = useState(
+ firstMenstrualPeriod.data.age != null
+ ? firstMenstrualPeriod.data.age.toString()
+ : "",
+ );
+
+ const [isRegular, setIsRegular] = useState(
+ regularCycles.data.isRegular != null ? regularCycles.data.isRegular : false,
+ );
+
+ const [isPainful, setIsPainful] = useState(
+ painfulMenstruation.data.isPainful != null
+ ? painfulMenstruation.data.isPainful
+ : false,
+ );
+
+ const [medication, setMedication] = useState(
+ painfulMenstruation.data.medication != null
+ ? painfulMenstruation.data.medication
+ : "",
+ );
+
+ const isFirstTime = !(
+ gynecologicalHistoryResult.result?.medicalHistory?.firstMenstrualPeriod
+ ?.data?.age ||
+ gynecologicalHistoryResult.result?.medicalHistory?.diagnosedIllnesses?.data
+ .length ||
+ gynecologicalHistoryResult.result?.medicalHistory?.hasSurgeries?.data.length
+ );
+
+ const [isEditable, setIsEditable] = useState(isFirstTime);
+
+ // TOTAL P SECTION
+
+ const [P, setP] = useState(
+ pregnancies.data.vaginalDeliveries != null
+ ? pregnancies.data.vaginalDeliveries
+ : 0,
+ );
+ const [C, setC] = useState(
+ pregnancies.data.cesareanSections != null
+ ? pregnancies.data.cesareanSections
+ : 0,
+ );
+ const [A, setA] = useState(
+ pregnancies.data.abortions != null ? pregnancies.data.abortions : 0,
+ ); // Abortos
+ const [G, setG] = useState(0);
+
+ useEffect(() => {
+ setG(P + C + A);
+ }, [P, C, A]);
+
+ // GENERAL INFO SECTION
+
+ // RENDER BASE INPUT IF MENSTRUATION IS PAINFUL
+ const renderMedicationInput = () => {
+ if (isPainful) {
+ return (
+
+
+ ¿Qué medicamento toma?
+
+
setMedication(e.target.value)}
+ readOnly={!isEditable}
+ placeholder="Ingrese el medicamento tomado para regular los dolores de menstruación."
+ style={{
+ width: "60%",
+ height: "3rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+ );
+ }
+ return null;
+ };
+
+ // DIAGNOSIS SECTION
+
+ const [diagnoses, setDiagnoses] = useState(() => {
+ const initialDiagnoses = [
+ {
+ key: "ovarianCysts",
+ title: "Diagnóstico por Quistes Ováricos:",
+ active: true,
+ details: diagnosedIllnesses.data.ovarianCysts?.medication || {},
+ },
+ {
+ key: "uterineMyomatosis",
+ title: "Diagnóstico por Miomatosis Uterina:",
+ active: true,
+ details: diagnosedIllnesses.data.uterineMyomatosis?.medication || {},
+ },
+ {
+ key: "endometriosis",
+ title: "Diagnóstico por Endometriosis:",
+ active: true,
+ details: diagnosedIllnesses.data.endometriosis?.medication || {},
+ },
+ ];
+
+ const otherConditions = diagnosedIllnesses.data?.otherCondition ?? [];
+ for (const condition of otherConditions) {
+ initialDiagnoses.push({
+ key: condition.medication.illness,
+ title: `Nuevo Diagnóstico: ${condition.medication.illness}`,
+ isNew: false,
+ active: true,
+ details: condition.medication,
+ });
+ }
+
+ return initialDiagnoses;
+ });
+
+ const addDiagnosis = () => {
+ const diagnosisCount = diagnoses.length + 1;
+
+ const newDiagnosis = {
+ key: `Nuevo Diagnóstico ${diagnosisCount}`,
+ title: `Nuevo Diagnóstico ${diagnosisCount}`,
+ isNew: true,
+ active: true,
+ details: {
+ illness: "",
+ medication: "",
+ dosage: "",
+ frequency: "",
+ },
+ };
+
+ setDiagnoses((prevDiagnoses) => [...prevDiagnoses, newDiagnosis]);
+ };
+
+ const removeDiagnosis = (key) => {
+ setDiagnoses(diagnoses.filter((diagnosis) => diagnosis.key !== key));
+ };
+
+ const getDiagnosisDetails = (key) => {
+ const diagnosis = diagnoses.find((d) => d.key === key);
+ if (!diagnosis?.active) {
+ return { dosage: "", frequency: "", medication: "", illness: "" };
+ }
+
+ if (["ovarianCysts", "uterineMyomatosis", "endometriosis"].includes(key)) {
+ return (
+ diagnosedIllnesses.data[key]?.medication || {
+ dosage: "",
+ frequency: "",
+ medication: "",
+ illness: "",
+ }
+ );
+ }
+
+ const condition = diagnosedIllnesses.data.otherCondition?.find(
+ (cond) => cond.medication.illness === key,
+ );
+
+ return condition?.medication
+ ? {
+ dosage: condition.medication.dosage || "",
+ frequency: condition.medication.frequency || "",
+ medication: condition.medication.medication || "",
+ illness: condition.medication.illness || "",
+ }
+ : {
+ dosage: "",
+ frequency: "",
+ medication: "",
+ illness: "",
+ };
+ };
+
+ const handleDiagnosedChange = (diagnosisKey, isActive, newDetails = {}) => {
+ setDiagnoses((prevDiagnoses) =>
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Ignoring complexity for this function
+ prevDiagnoses.map((diagnosis) => {
+ if (diagnosis.key === diagnosisKey) {
+ if (!isActive) {
+ return {
+ ...diagnosis,
+ active: false,
+ details: { medication: "", dosage: "", frequency: "" },
+ };
+ // biome-ignore lint/style/noUselessElse: Handles the data structure of the diagnoses for static ones and the new diagnostics
+ } else {
+ const updatedDetails = {
+ medication:
+ newDetails.medication || diagnosis.details.medication || "",
+ dosage: newDetails.dosage || diagnosis.details.dosage || "",
+ frequency:
+ newDetails.frequency || diagnosis.details.frequency || "",
+ };
+
+ if (
+ diagnosis.isNew &&
+ diagnosis.key.startsWith("Nuevo Diagnóstico")
+ ) {
+ updatedDetails.illness =
+ newDetails.illness || diagnosis.details.illness || "";
+ }
+
+ return {
+ ...diagnosis,
+ active: true,
+ details: updatedDetails,
+ };
+ }
+ }
+ return diagnosis;
+ }),
+ );
+ };
+
+ // OPERACIONES SECTION
+
+ const [operations, setOperations] = useState(() => {
+ const initialOperations = [
+ {
+ key: "hysterectomy",
+ title: "Operación por Histerectomía:",
+ details: hasSurgeries.data.hysterectomy || {},
+ },
+ {
+ key: "sterilization",
+ title: "Cirugía para no tener más hijos:",
+ details: hasSurgeries.data.sterilizationSurgery || {},
+ },
+ {
+ key: "ovarianCysts",
+ title: "Operación por Quistes Ováricos:",
+ details: hasSurgeries.data.ovarianCystsSurgery || [],
+ },
+ {
+ key: "breastMassResection",
+ title: "Operación por Resección de masas en mamas:",
+ details: hasSurgeries.data.breastMassResection || [],
+ },
+ ];
+
+ return initialOperations;
+ });
+
+ const mapOperationDetails = (operationKey) => {
+ const operation = operations.find((op) => op.key === operationKey);
+ if (!operation) return {};
+ return operation.details;
+ };
+
+ const updateGlobalOperations = (operationKey, newDetails) => {
+ setOperations(
+ operations.map((op) => {
+ if (op.key === operationKey) {
+ return { ...op, details: newDetails };
+ }
+ return op;
+ }),
+ );
+ };
+
+ const handlePerformedChange = (operationKey, isPerformed) => {
+ setOperations((prevOperations) =>
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Ignoring complexity for this function
+ prevOperations.map((operation) => {
+ if (operation.key === operationKey) {
+ const clearedDetails = isPerformed
+ ? operation.details
+ : operation.key === "ovarianCysts" ||
+ operation.key === "breastMassResection"
+ ? []
+ : {};
+
+ return {
+ ...operation,
+ details: clearedDetails,
+ };
+ }
+ return operation;
+ }),
+ );
+ };
+
+ const validateGynecologicalHistory = () => {
+ if (!age || Number.isNaN(age) || Number(age) < 1) {
+ toast.error("Por favor, ingrese una edad válida.");
+ return false;
+ }
+
+ if (
+ !Number.isInteger(G) ||
+ G < 0 ||
+ !Number.isInteger(C) ||
+ C < 0 ||
+ !Number.isInteger(A) ||
+ A < 0 ||
+ G < C + A
+ ) {
+ toast.error("Por favor, ingrese datos válidos en la sección de partos.");
+ return false;
+ }
+
+ if (isPainful && medication.trim() === "") {
+ toast.error(
+ "Por favor, complete los detalles del medicamento para la menstruación dolorosa.",
+ );
+ return false;
+ }
+
+ const invalidDiagnosis = diagnoses.some((diagnosis) => {
+ const { medication, dosage, frequency } = diagnosis.details;
+
+ if (diagnosis.active) {
+ const initialDetails = getDiagnosisDetails(diagnosis.key);
+ const isInitiallyFilled = (field) =>
+ initialDetails[field] && initialDetails[field].trim() !== "";
+
+ return (
+ (isInitiallyFilled("medication") && medication.trim() === "") ||
+ (isInitiallyFilled("dosage") && dosage.trim() === "") ||
+ (isInitiallyFilled("frequency") && frequency.trim() === "")
+ );
+ }
+ return false;
+ });
+
+ if (invalidDiagnosis) {
+ toast.error(
+ "Por favor, complete los detalles de todos los diagnósticos activos.",
+ );
+ return false;
+ }
+
+ const invalidOperation = operations.some((operation) => {
+ const details = Array.isArray(operation.details)
+ ? operation.details
+ : [operation.details];
+ return details.some((detail) => detail.year === null);
+ });
+
+ if (invalidOperation) {
+ toast.error("Por favor, complete los detalles de todas las operaciones.");
+ return false;
+ }
+
+ return true;
+ };
+ const structuredOperations = operations.reduce((acc, operation) => {
+ const details = mapOperationDetails(operation.key);
+
+ acc[operation.key] = Array.isArray(details)
+ ? details.map(({ year = null, complications = false }) => ({
+ year,
+ complications,
+ }))
+ : { ...details };
+
+ return acc;
+ }, {});
+
+ const fixedDiagnosesKeys = [
+ "ovarianCysts",
+ "uterineMyomatosis",
+ "endometriosis",
+ ];
+
+ // Canceling update
+ const handleCancel = () => {
+ setIsEditable(false);
+ toast.info("Edición cancelada.");
+ };
+
+ const formattedDiagnosedIllnesses = {
+ version: diagnosedIllnesses?.version || 1,
+ data: diagnoses.reduce((acc, diagnosis) => {
+ if (fixedDiagnosesKeys.includes(diagnosis.key)) {
+ acc[diagnosis.key] = {
+ medication: { ...diagnosis.details },
+ };
+ } else {
+ acc.otherCondition = acc.otherCondition || [];
+ acc.otherCondition.push({
+ medication: {
+ illness: diagnosis.key,
+ ...diagnosis.details,
+ },
+ });
+ }
+ return acc;
+ }, {}),
+ };
+
+ const handleSaveGynecologicalHistory = async () => {
+ if (!validateGynecologicalHistory()) {
+ return;
+ }
+
+ const medicalHistory = {
+ firstMenstrualPeriod: {
+ version: firstMenstrualPeriod?.version || 1,
+ data: {
+ age: age,
+ },
+ },
+ regularCycles: {
+ version: regularCycles?.version || 1,
+ data: {
+ isRegular: isRegular,
+ },
+ },
+ painfulMenstruation: {
+ version: painfulMenstruation?.version || 1,
+ data: {
+ isPainful: isPainful,
+ medication: medication,
+ },
+ },
+ pregnancies: {
+ version: pregnancies?.version || 1,
+ data: {
+ totalPregnancies: G,
+ vaginalDeliveries: P,
+ cesareanSections: C,
+ abortions: A,
+ },
+ },
+ diagnosedIllnesses: formattedDiagnosedIllnesses,
+ hasSurgeries: {
+ version: hasSurgeries?.version || 1,
+ data: {
+ hysterectomy: structuredOperations.hysterectomy || {},
+ sterilizationSurgery: structuredOperations.sterilization || {},
+ ovarianCystsSurgery: structuredOperations.ovarianCysts || null,
+ breastMassResection: structuredOperations.breastMassResection || [],
+ },
+ },
+ };
+
+ toast.info("Guardando antecedente ginecoobstétrico...");
+
+ const result = await updateObGynHistory(id, medicalHistory);
+ if (!result.error) {
+ toast.success("Antecedentes ginecoobstétricos actualizados con éxito.");
+ triggerReload();
+ setIsEditable(false);
+ } else {
+ toast.error(
+ `Error al actualizar los antecedentes ginecoobstétricos: ${result.error}`,
+ );
+ }
+ };
+
+ useEffect(() => {
+ console.log("isEditable changed to:", isEditable);
+ }, [isEditable]);
+
+ return (
+
+
+ {errorMessage ? (
+
+ {errorMessage}
+
+ ) : (
+ <>
+ {isFirstTime && (
+
+ Por favor, ingrese los datos del paciente. Parece que es su
+ primera visita aquí.
+
+ )}
+
+
+
+ Información General:{" "}
+
+
+ {!isFirstTime &&
+ (isEditable ? (
+
+
+
+
+ ) : (
+
setIsEditable(true)}
+ />
+ ))}
+
+
+
+ Ingrese la edad en la que tuvo la primera mestruación:
+
+
setAge(e.target.value)}
+ readOnly={!isEditable}
+ placeholder="Ingrese la edad (Ej. 15, 16...)"
+ style={{
+ width: "60%",
+ height: "3rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+ ¿Sus ciclos son regulares? (Ciclos de 21-35 días)
+
+
+ setIsRegular(true)}
+ label="Sí"
+ disabled={!isEditable}
+ />
+ setIsRegular(false)}
+ label="No"
+ disabled={!isEditable}
+ />
+
+
+ ¿Normalmente tiene menstruación dolorosa?
+
+
+ setIsPainful(true)}
+ label="Sí"
+ disabled={!isEditable}
+ />
+ {
+ setIsPainful(false);
+ setMedication("");
+ }}
+ label="No"
+ disabled={!isEditable}
+ />
+
+
+ {renderMedicationInput()}
+
+
+
+
+
+ {" "}
+ ={" "}
+
+
+
+ P:
+
+
setP(Number(e.target.value) || 0)}
+ readOnly={!isEditable}
+ placeholder="# vía vaginal"
+ style={{
+ width: "100%",
+ height: "2.5rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+
+ {" "}
+ +{" "}
+
+
+
+ C:
+
+
setC(Number(e.target.value) || 0)}
+ readOnly={!isEditable}
+ placeholder="# cesáreas"
+ style={{
+ width: "100%",
+ height: "2.5rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+
+ {" "}
+ +{" "}
+
+
+
+ A:
+
+
setA(Number(e.target.value) || 0)}
+ readOnly={!isEditable}
+ placeholder="# abortos"
+ style={{
+ width: "100%",
+ height: "2.5rem",
+ fontFamily: fonts.textFont,
+ fontSize: "1rem",
+ }}
+ />
+
+
+
+
+
+
+
+ Diagnóstico de Enfermedades{" "}
+
+
+ {diagnoses.map((diagnosis, index) => (
+
+
removeDiagnosis(diagnosis.key)}
+ diagnosisDetails={getDiagnosisDetails(diagnosis.key)}
+ handleDiagnosedChange={handleDiagnosedChange}
+ isFirstTime={isFirstTime}
+ />
+ {index < diagnoses.length - 1 && (
+
+ )}
+
+ ))}
+
+
+ {(isFirstTime || isEditable) && (
+
+ )}
+
+
+
+ Operaciones del Paciente:{" "}
+
+
+ {operations.map((operation, index) => (
+
+
+ {index < operations.length - 1 && (
+
+ )}
+
+ ))}
+
+
+ {isFirstTime && (
+
+
+
+ )}
+
+
+ >
+ )}
+
+
+ );
+}
diff --git a/sanitas_frontend/src/views/History/ObGyn/index.stories.jsx b/sanitas_frontend/src/views/History/ObGyn/index.stories.jsx
new file mode 100644
index 00000000..31b4c555
--- /dev/null
+++ b/sanitas_frontend/src/views/History/ObGyn/index.stories.jsx
@@ -0,0 +1,232 @@
+import { MemoryRouter, Route, Routes } from "react-router-dom";
+import { ObGynHistory } from "src/views/History/ObGyn";
+import { createEmptyStore } from "src/store.mjs";
+
+// Mock functions and data
+const mockGetBirthdayPatientInfo = async () => ({
+ result: {
+ birthdate: "1980-01-01",
+ },
+});
+
+const mockGetObGynHistoryWithData = async () => ({
+ result: {
+ medicalHistory: {
+ firstMenstrualPeriod: { data: { age: 15 } },
+ regularCycles: { data: { isRegular: true } },
+ painfulMenstruation: { data: { isPainful: false, medication: "" } },
+ pregnancies: {
+ data: {
+ totalPregnancies: 2,
+ abortions: 0,
+ cesareanSections: 1,
+ vaginalDeliveries: 1,
+ },
+ },
+ diagnosedIllnesses: {
+ data: {
+ ovarianCysts: {
+ medication: {
+ dosage: "100mg",
+ frequency: "Daily",
+ medication: "Ibuprofen",
+ },
+ },
+ uterineMyomatosis: {
+ medication: {
+ dosage: "50mg",
+ frequency: "Twice a day",
+ medication: "Paracetamol",
+ },
+ },
+ endometriosis: {
+ medication: { dosage: "", frequency: "", medication: "" },
+ },
+ otherCondition: [
+ {
+ medication: {
+ illness: "illness A",
+ medication: "Med D",
+ dosage: "500mg",
+ frequency: "Once a day",
+ },
+ },
+ ],
+ },
+ },
+ hasSurgeries: {
+ data: {
+ ovarianCystsSurgery: [{ year: 2005, complications: false }],
+ hysterectomy: { year: 2010, complications: true },
+ sterilizationSurgery: { year: null, complications: false },
+ breastMassResection: [{ year: 2015, complications: false }],
+ },
+ },
+ },
+ },
+});
+
+const mockGetObGynHistoryEmpty = async () => ({
+ result: {
+ medicalHistory: {
+ firstMenstrualPeriod: { data: { age: null } },
+ regularCycles: { data: { isRegular: null } },
+ painfulMenstruation: { data: { isPainful: null, medication: "" } },
+ pregnancies: {
+ data: {
+ totalPregnancies: null,
+ abortions: null,
+ cesareanSections: null,
+ vaginalDeliveries: null,
+ },
+ },
+ diagnosedIllnesses: {
+ data: {
+ ovarianCysts: {},
+ uterineMyomatosis: {},
+ endometriosis: {},
+ otherCondition: [],
+ },
+ },
+ hasSurgeries: {
+ data: {
+ ovarianCystsSurgery: [],
+ hysterectomy: {},
+ sterilizationSurgery: {},
+ breastMassResection: [],
+ },
+ },
+ },
+ },
+});
+
+const mockGetObGynHistoryError = async () => ({
+ result: {
+ medicalHistory: {
+ firstMenstrualPeriod: { data: { age: 15 } },
+ regularCycles: { data: { isRegular: true } },
+ painfulMenstruation: { data: { isPainful: false, medication: "" } },
+ pregnancies: {
+ data: {
+ totalPregnancies: 2,
+ abortions: 0,
+ cesareanSections: 1,
+ vaginalDeliveries: 1,
+ },
+ },
+ diagnosedIllnesses: {
+ data: {
+ ovarianCysts: {
+ medication: {
+ dosage: "100mg",
+ frequency: "Daily",
+ medication: "Ibuprofen",
+ },
+ },
+ uterineMyomatosis: {
+ medication: {
+ dosage: "50mg",
+ frequency: "Twice a day",
+ medication: "Paracetamol",
+ },
+ },
+ endometriosis: {
+ medication: { dosage: "", frequency: "", medication: "" },
+ },
+ otherCondition: [
+ {
+ medication: {
+ illness: "illness A",
+ medication: "Med D",
+ dosage: "500mg",
+ frequency: "Once a day",
+ },
+ },
+ ],
+ },
+ },
+ hasSurgeries: {
+ data: {
+ ovarianCystsSurgery: [{ year: 2005, complications: false }],
+ hysterectomy: { year: 2010, complications: true },
+ sterilizationSurgery: { year: null, complications: false },
+ breastMassResection: [{ year: 2015, complications: false }],
+ },
+ },
+ },
+ },
+ error: {
+ response: {
+ status: 400,
+ statusText: "Bad Request",
+ data: "Invalid request parameters.",
+ },
+ },
+});
+
+const mockUpdateObGynHistory = async () => ({
+ success: true,
+});
+
+const store = createEmptyStore({
+ selectedPatientId: 12345, // Mock patient ID
+});
+
+export default {
+ title: "Views/Antecedents/ObGynHistory",
+ component: ObGynHistory,
+ decorators: [
+ (Story) => (
+
+
+ } />
+
+
+ ),
+ ],
+};
+
+export const WithData = {
+ args: {
+ getBirthdayPatientInfo: mockGetBirthdayPatientInfo,
+ getObGynHistory: mockGetObGynHistoryWithData,
+ updateObGynHistory: mockUpdateObGynHistory,
+ sidebarConfig: {
+ userInformation: {
+ displayName: "Dr. Jane Doe",
+ title: "Ginecóloga",
+ },
+ },
+ useStore: () => ({ selectedPatientId: store.selectedPatientId }),
+ },
+};
+
+export const EmptyData = {
+ args: {
+ getBirthdayPatientInfo: mockGetBirthdayPatientInfo,
+ getObGynHistory: mockGetObGynHistoryEmpty,
+ updateObGynHistory: mockUpdateObGynHistory,
+ sidebarConfig: {
+ userInformation: {
+ displayName: "Dr. Jane Doe",
+ title: "Ginecóloga",
+ },
+ },
+ useStore: () => ({ selectedPatientId: store.selectedPatientId }),
+ },
+};
+
+export const ErrorState = {
+ args: {
+ getBirthdayPatientInfo: mockGetBirthdayPatientInfo,
+ getObGynHistory: mockGetObGynHistoryError,
+ updateObGynHistory: mockUpdateObGynHistory,
+ sidebarConfig: {
+ userInformation: {
+ displayName: "Dr. Jane Doe",
+ title: "Ginecóloga",
+ },
+ },
+ useStore: () => ({ selectedPatientId: store.selectedPatientId }),
+ },
+};
diff --git a/sanitas_frontend/src/views/History/ObGyn/index.test.jsx b/sanitas_frontend/src/views/History/ObGyn/index.test.jsx
new file mode 100644
index 00000000..a22ec1a9
--- /dev/null
+++ b/sanitas_frontend/src/views/History/ObGyn/index.test.jsx
@@ -0,0 +1,304 @@
+import {
+ render,
+ screen,
+ fireEvent,
+ waitForElementToBeRemoved,
+ waitFor,
+} from "@testing-library/react";
+import { MemoryRouter } from "react-router-dom";
+import { describe, expect, test, vi } from "vitest";
+import { toast } from "react-toastify";
+import { ObGynHistory } from ".";
+
+vi.mock("react-toastify", () => ({
+ toast: {
+ error: vi.fn(),
+ success: vi.fn(),
+ info: vi.fn(),
+ },
+}));
+
+const mockGetBirthdayPatientInfo = async () => ({
+ result: {
+ birthdate: "1980-01-01",
+ },
+});
+
+const mockGetObGynHistoryWithData = async () => ({
+ result: {
+ medicalHistory: {
+ firstMenstrualPeriod: { data: { age: 15 } },
+ regularCycles: { data: { isRegular: true } },
+ painfulMenstruation: { data: { isPainful: false, medication: "" } },
+ pregnancies: {
+ data: {
+ totalPregnancies: 2,
+ abortions: 0,
+ cesareanSections: 1,
+ vaginalDeliveries: 1,
+ },
+ },
+ diagnosedIllnesses: {
+ data: {
+ ovarianCysts: {
+ medication: {
+ dosage: "100mg",
+ frequency: "Daily",
+ medication: "Ibuprofen",
+ },
+ },
+ uterineMyomatosis: {
+ medication: {
+ dosage: "50mg",
+ frequency: "Twice a day",
+ medication: "Paracetamol",
+ },
+ },
+ endometriosis: {
+ medication: { dosage: "", frequency: "", medication: "" },
+ },
+ otherCondition: [
+ {
+ medication: {
+ illness: "illness A",
+ medication: "Med D",
+ dosage: "500mg",
+ frequency: "Once a day",
+ },
+ },
+ ],
+ },
+ },
+ hasSurgeries: {
+ data: {
+ ovarianCystsSurgery: [{ year: 2005, complications: false }],
+ hysterectomy: { year: 2010, complications: true },
+ sterilizationSurgery: { year: 2015, complications: false },
+ breastMassResection: [{ year: 2015, complications: false }],
+ },
+ },
+ },
+ },
+});
+
+const mockGetObGynHistoryError = async () => ({
+ result: {
+ medicalHistory: {
+ firstMenstrualPeriod: { data: { age: 15 } },
+ regularCycles: { data: { isRegular: true } },
+ painfulMenstruation: { data: { isPainful: false, medication: "" } },
+ pregnancies: {
+ data: {
+ totalPregnancies: 2,
+ abortions: 0,
+ cesareanSections: 1,
+ vaginalDeliveries: 1,
+ },
+ },
+ diagnosedIllnesses: {
+ data: {
+ ovarianCysts: {
+ medication: {
+ dosage: "100mg",
+ frequency: "Daily",
+ medication: "Ibuprofen",
+ },
+ },
+ uterineMyomatosis: {
+ medication: {
+ dosage: "50mg",
+ frequency: "Twice a day",
+ medication: "Paracetamol",
+ },
+ },
+ endometriosis: {
+ medication: { dosage: "", frequency: "", medication: "" },
+ },
+ otherCondition: [
+ {
+ medication: {
+ illness: "illness A",
+ medication: "Med D",
+ dosage: "500mg",
+ frequency: "Once a day",
+ },
+ },
+ ],
+ },
+ },
+ hasSurgeries: {
+ data: {
+ ovarianCystsSurgery: [{ year: 2005, complications: false }],
+ hysterectomy: { year: 2010, complications: true },
+ sterilizationSurgery: { year: 2015, complications: false },
+ breastMassResection: [{ year: 2015, complications: false }],
+ },
+ },
+ },
+ },
+ error: {
+ response: {
+ status: 400,
+ statusText: "Bad Request",
+ data: "Invalid request parameters.",
+ },
+ },
+});
+
+const mockUpdateObGynHistory = vi.fn(() => Promise.resolve({ success: true }));
+const mockUseStore = vi.fn().mockReturnValue({ selectedPatientId: "12345" });
+
+const Wrapper = ({ children }) => {children};
+
+describe("ObGynHistory Component Tests", () => {
+ test("renders and displays general information", async () => {
+ render(
+
+
+ ,
+ );
+
+ await waitFor(() =>
+ expect(
+ screen.queryByText(
+ "Cargando información de los antecedentes ginecoobstétricos...",
+ ),
+ ).not.toBeInTheDocument(),
+ );
+
+ expect(
+ screen.getByText("Antecedentes Ginecoobstétricos"),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByText("Registro de antecedentes ginecoobstétricos"),
+ ).toBeInTheDocument();
+
+ const diagnosisText = document
+ .querySelector("div")
+ .textContent.includes("Diagnóstico por Quistes Ováricos:");
+ expect(diagnosisText).toBe(true);
+ });
+
+ test("handles the addition of a new diagnosis", async () => {
+ render(
+
+
+ ,
+ );
+
+ await waitForElementToBeRemoved(() =>
+ screen.queryByText(
+ "Cargando información de los antecedentes ginecoobstétricos...",
+ ),
+ );
+
+ const allIcons = await screen.findAllByRole("img", { name: "Icon" });
+ const editIcon = allIcons.find((icon) =>
+ icon.src.includes("outline/edit.svg"),
+ );
+ const editButton = editIcon.closest("button");
+ fireEvent.click(editButton);
+ //fireEvent.click(editButtons[0]);
+
+ const addButton = await screen.findByText("Agregar otro diagnóstico");
+ fireEvent.click(addButton);
+
+ const diagnosisInput = await screen.findByPlaceholderText(
+ "Ingrese el nombre del diagnóstico.",
+ );
+ expect(diagnosisInput).toBeInTheDocument();
+ });
+
+ test("displays error message when there is an error fetching data", async () => {
+ render(
+
+
+ ,
+ );
+
+ await waitForElementToBeRemoved(() =>
+ screen.queryByText(
+ "Cargando información de los antecedentes ginecoobstétricos...",
+ ),
+ );
+
+ await waitFor(() => {
+ const errorMessage = screen.getByText(
+ /Ha ocurrido un error en la búsqueda, ¡Por favor vuelve a intentarlo!/i,
+ );
+ expect(errorMessage).toBeInTheDocument();
+ });
+ });
+
+ test("saves gynecological history successfully", async () => {
+ render(
+
+
+ ,
+ );
+
+ await waitFor(
+ () => {
+ const loadingMessage = screen.queryByText(
+ "Cargando información de los antecedentes ginecoobstétricos...",
+ );
+ expect(loadingMessage).not.toBeInTheDocument();
+ },
+ { timeout: 5000 },
+ );
+
+ const allIconsBeforeEdit = await screen.findAllByRole("img", {
+ name: "Icon",
+ });
+ const editIcon = allIconsBeforeEdit.find((icon) =>
+ icon.src.includes("outline/edit.svg"),
+ );
+ const editButton = editIcon.closest("button");
+ fireEvent.click(editButton);
+
+ const allIconsAfterEdit = await screen.findAllByRole("img", {
+ name: "Icon",
+ });
+ const checkIcon = allIconsAfterEdit.find((icon) =>
+ icon.src.includes("outline/check.svg"),
+ );
+ const checkButton = checkIcon.closest("button");
+ fireEvent.click(checkButton);
+
+ await waitFor(() =>
+ expect(toast.success).toHaveBeenCalledWith(
+ "Antecedentes ginecoobstétricos actualizados con éxito.",
+ ),
+ );
+ });
+});