All files / hooks vaccineData.ts

87.17% Statements 34/39
62.5% Branches 5/8
87.5% Functions 7/8
86.84% Lines 33/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144                                                                                  6x   6x 6x 6x   6x 3x 3x             3x       6x 3x       6x 6x 6x   6x           6x                                           8x 8x                     8x 4x   4x 4x 4x   4x           4x 4x 3x   1x 1x 1x       4x   4x 4x       8x        
import VaccineDataController from "@/controllers/vaccineDataController";
import {
  iVaccineDataController,
  VaccineSheet,
} from "@/interfaces/iVaccineData";
import logger from "@/utils/logger";
import * as Network from "expo-network";
import { useEffect, useState } from "react";
 
export type VaccineSheetStatus = {
  /** holds the list of vaccines */
  vaccineSheets: VaccineSheet[];
  /** true if the vaccine list is still loading, otherwise false */
  loading: boolean;
  /** if an error occures a string representing the error is stored */
  error?: string;
}
 
/**
 * Retrieves the list of vaccine sheets.
 *
 * @param {Object} data The configuration for getting clinic information.
 * @param {iVaccineDataController} data.vaccineController The interface to use to access the vaccine data.
 * @param {string} [data.searchValue] Value to search for in the list of clinics.
 *   If null it gets all of the clinics.
 * @param {string} [data.searchColumn] The column to search for `searchValue` in.
 *   Ignored unless `searchValue` is set. If null, all columns are searched.
 *
 * @returns {VaccineSheetStatus} Object representing the current status of vaccine data loading, containing:
 *   @property {VaccineSheet[]}
 *      A list of vaccine sheets to be displayed
 *   @property {boolean} `loading`
 *      `true` if the data is still loading, otherwise `false`.
 *   @property {string | null} `error`
 *      An error message if an error occurred, or `null` if no error.
 */
export function useVaccineSheets(data: {
  vaccineController: iVaccineDataController;
  searchValue?: string;
  searchColumn?: string;
}): VaccineSheetStatus {
  const { vaccineController, searchValue, searchColumn } = data;
 
  const [vaccineSheets, setVaccineSheets] = useState<VaccineSheet[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
 
  const fetchResults = async () => {
    try {
      setVaccineSheets(
        await vaccineController.searchVaccines(searchValue, searchColumn)
      );
    } catch (error) {
      logger.error(error);
      setError(String(error));
    } finally {
      setLoading(false);
    }
  };
 
  useEffect(() => {
    fetchResults();
  }, [searchValue, searchColumn]);
 
  //logger.debug("useVaccineSheets -> vaccineSheets:", vaccineSheets[0].associatedDiseases);
  logger.debug("useVaccineSheets -> loading:", loading);
  logger.debug("useVaccineSheets -> error:", error);
  logger.debug("useVaccineSheets -> fetchResults:", fetchResults);
 
  const response = {
    vaccineSheets: vaccineSheets,
    loading: loading,
    error: error ?? undefined,
  };
 
  return response;
}
 
/**
 *
 * Updates the vaccine sheets as well as the vaccine list. This is run when the
 * application starts up.
 * 
 * @precondition There is an internet conneciton (checked within this function)
 *
 * @param {iVaccineDataController} vaccineController The interface to use to access the vaccine data.
 * @returns {Object}
 *    @property {boolean} success if the update was a success this will be true
 *    Even if no files are updated, if there are no errors this will be true
 *    @property {number} updated the number of files updated.
 *    @property {failed} number  the number of files attempted to be updated
 *    that failed.
 *    @property {error | undefined} Error if there is an error in the update
 *    it is shown here.
 *
 */
export function useUpdateVaccineSheets(vaccineController: iVaccineDataController) {
  const [isConnected, setIsConnected] = useState<boolean | undefined>(undefined);
  const [result, setResult] = useState<{
    success: boolean;
    updated: number;
    failed: number;
    error?: Error;
  }>({
    success: false,
    updated: 0,
    failed: 0,
  });
 
  useEffect(() => {
    let isMounted = true; // Prevent updates after unmount
 
    const tryUpdate = async () => {
      const state = await Network.getNetworkStateAsync();
      setIsConnected(state.isConnected);
 
      Iif (!state.isConnected) {
        logger.debug(state.isConnected);
        logger.error("No network connection");
        return; // Don't run if offline
      }
 
      try {
        const updateResult = await vaccineController.updateVaccines();
        Eif (isMounted) setResult(updateResult);
      } catch (error: any) {
        logger.error(error);
        Eif (isMounted)
          setResult({ success: false, updated: 0, failed: 0, error });
      }
    };
 
    tryUpdate();
 
    return () => {
      isMounted = false; // Cleanup function to prevent memory leaks
    };
  }, []); // Empty dependency array → Runs once when app starts
 
  return result;
}
 
export function useVaccinePDF(uri: string) {}