department-of-veterans-affairs/vets-website

View on GitHub
src/applications/mhv-medications/containers/PrescriptionDetailsDocumentation.jsx

Summary

Maintainability
C
1 day
Test Coverage
import React, { useCallback, useEffect, useState, useRef } from 'react';
import { useParams, useLocation } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import FEATURE_FLAG_NAMES from '@department-of-veterans-affairs/platform-utilities/featureFlagNames';
import PageNotFound from '@department-of-veterans-affairs/platform-site-wide/PageNotFound';
import { updatePageTitle } from '@department-of-veterans-affairs/mhv/exports';
import { focusElement } from '@department-of-veterans-affairs/platform-utilities/ui';
import { getDocumentation } from '../api/rxApi';
import { getPrescriptionDetails } from '../actions/prescriptions';
import ApiErrorNotification from '../components/shared/ApiErrorNotification';
import {
  dateFormat,
  sanitizeKramesHtmlStr,
  generateTextFile,
  generateMedicationsPDF,
  convertHtmlForDownload,
} from '../util/helpers';
import PrintDownload from '../components/shared/PrintDownload';
import { buildMedicationInformationPDF } from '../util/pdfConfigs';
import { DOWNLOAD_FORMAT } from '../util/constants';
import { pageType } from '../util/dataDogConstants';
import BeforeYouDownloadDropdown from '../components/shared/BeforeYouDownloadDropdown';

const PrescriptionDetailsDocumentation = () => {
  const { prescriptionId } = useParams();
  const { search } = useLocation();
  const queryParams = new URLSearchParams(search);
  const ndcNumber = queryParams.get('ndc');
  const contentRef = useRef();
  const {
    prescription,
    isDisplayingDocumentation,
    hasPrescriptionApiError,
    dob,
    userName,
  } = useSelector(state => ({
    prescription: state.rx.prescriptions.prescriptionDetails,
    isDisplayingDocumentation:
      state.featureToggles[
        FEATURE_FLAG_NAMES.mhvMedicationsDisplayDocumentationContent
      ],
    hasPrescriptionApiError: state.rx.prescriptions?.apiError,
    userName: state.user.profile.userFullName,
    dob: state.user.profile.dob,
  }));

  const dispatch = useDispatch();
  const [htmlContent, setHtmlContent] = useState(null);
  const [hasDocApiError, setHasDocApiError] = useState(false);
  const [isLoadingDoc, setIsLoadingDoc] = useState(false);
  const [isLoadingRx, setIsLoadingRx] = useState(false);
  useEffect(
    () => {
      if (prescriptionId && ndcNumber) {
        setIsLoadingDoc(true);
        getDocumentation(prescriptionId, ndcNumber)
          .then(response => {
            setHasDocApiError(false);
            setHtmlContent(
              sanitizeKramesHtmlStr(response.data.attributes.html),
            );
          })
          .catch(() => {
            setHasDocApiError(true);
          })
          .finally(() => {
            setIsLoadingDoc(false);
          });
      }
    },
    [prescriptionId, ndcNumber],
  );

  useEffect(
    () => {
      if (!prescription && prescriptionId && ndcNumber) {
        setIsLoadingRx(true);
        dispatch(getPrescriptionDetails(prescriptionId));
      } else if (prescription && prescriptionId && ndcNumber && isLoadingRx) {
        setIsLoadingRx(false);
      }
    },
    [prescriptionId, ndcNumber, prescription, dispatch, isLoadingRx],
  );

  const buildMedicationInformationTxt = useCallback(
    information => {
      return (
        `${"\nIf you're ever in crisis and need to talk with someone right away, call the Veterans Crisis Line at 988. Then select 1.\n\n\n" +
          `Information: ${prescription.prescriptionName}\n`}${
          userName.first
            ? `${userName.last}, ${userName.first}`
            : userName.last || ' '
        }\n` +
        `This is a summary and does NOT have all possible information about this product. This information does not assure that this product is safe, effective, or appropriate for you. This information is not individual medical advice and does not substitute for the advice of your health care professional. Always ask your health care professional for complete information about this product and your specific health needs.\n\n\n\n` +
        `Date of birth: ${dateFormat(dob, 'MMMM D, YYYY')}\n\n` +
        `Report generated by My HealtheVet on VA.gov on ${dateFormat(
          Date.now(),
          'MMMM D, YYYY',
        )}\n\n---------------------------------------------------------------------------------\n\n\n` +
        `${information}`
      );
    },
    [userName, dob, prescription],
  );

  useEffect(() => {
    updatePageTitle(`More about this medication | Veteran Affairs`);
  }, []);

  const downloadText = () => {
    const formattedText = convertHtmlForDownload(htmlContent);
    const textData = buildMedicationInformationTxt(formattedText);
    generateTextFile(
      textData,
      `medication-information-${prescription.prescriptionName}-${
        userName.first ? `${userName.first}-${userName.last}` : userName.last
      }-${dateFormat(Date.now(), 'M-D-YYYY').replace(/\./g, '')}`,
    );
  };

  const downloadPdf = async () => {
    const formattedText = convertHtmlForDownload(
      htmlContent,
      DOWNLOAD_FORMAT.PDF,
    );
    const pdfData = buildMedicationInformationPDF(formattedText);
    const setup = {
      subject: 'Medication Information',
      headerBanner: [
        {
          text:
            'If you’re ever in crisis and need to talk with someone right away, call the Veterans Crisis Line at ',
        },
        {
          text: '988',
          weight: 'bold',
        },
        {
          text: '. Then select 1.',
        },
      ],
      footerRight: 'Page %PAGE_NUMBER% of %TOTAL_PAGES%',
      title: `Medication information: ${prescription?.prescriptionName}`,
      preface: [
        {
          value: `Important: How to use this information`,
          weight: 'bold',
          paragraphGap: 0,
        },
        {
          value: `This is a summary and does NOT have all possible information about this product. This information does not assure that this product is safe, effective, or appropriate for you. This information is not individual medical advice and does not substitute for the advice of your health care professional. Always ask your health care professional for complete information about this product and your specific health needs.`,
        },
      ],
      results: [{ list: [pdfData] }],
    };
    await generateMedicationsPDF(
      'medications',
      `medication-information-${prescription.prescriptionName}-${dateFormat(
        Date.now(),
        'M-D-YYYY',
      ).replace(/\./g, '')}`,
      setup,
    );
  };

  const printPage = () => window.print();

  useEffect(
    () => {
      if (!isLoadingDoc && !hasDocApiError && !isLoadingRx && htmlContent) {
        contentRef.current.innerHTML = htmlContent ?? '';
      }
      focusElement(document.querySelector('h1'));
    },
    [isLoadingDoc, isLoadingRx, hasDocApiError, htmlContent],
  );

  if (!isDisplayingDocumentation) {
    return <PageNotFound />;
  }
  if (hasDocApiError || hasPrescriptionApiError) {
    return (
      <div className="vads-u-margin-top--1">
        <ApiErrorNotification
          errorType="access"
          content="medication information"
        />
      </div>
    );
  }

  return (
    <>
      {isLoadingDoc || isLoadingRx || !htmlContent ? (
        <va-loading-indicator message="Loading information..." set-focus />
      ) : (
        <div>
          <h1 data-testid="medication-information">
            Medication information: {prescription?.prescriptionName}
          </h1>
          <PrintDownload
            onPrint={printPage}
            onText={downloadText}
            onDownload={downloadPdf}
            isSuccess={false}
          />
          <BeforeYouDownloadDropdown page={pageType.DOCUMENTATION} />
          <div className="no-print rx-page-total-info vads-u-border-bottom--2px vads-u-border-color--gray-lighter vads-u-margin-y--5" />
          <va-on-this-page />
          <p className="vads-u-font-weight--bold vads-u-font-family--serif">
            Important: How to Use This Information
          </p>
          <p className="vads-u-font-family--serif">
            This is a summary and does NOT have all possible information about
            this product. This information does not assure that this product is
            safe, effective, or appropriate for you. This information is not
            individual medical advice and does not substitute for the advice of
            your health care professional. Always ask your health care
            professional for complete information about this product and your
            specific health needs.
          </p>
        </div>
      )}
      {/* NOTE: The HTML content comes from a reliable source (MHV API/Krames API) */}
      <article>
        <div ref={contentRef} />
      </article>
    </>
  );
};

export default PrescriptionDetailsDocumentation;