From 1d67d55ea8ee8b185734f32cb6c71650d5439860 Mon Sep 17 00:00:00 2001
From: Eric Lipe <elipe@teamraft.com>
Date: Wed, 27 Sep 2023 13:15:04 -0600
Subject: [PATCH 1/6] - Updated request to execute 5 times before throwing
 error

---
 .../src/components/STTComboBox/STTComboBox.jsx         | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
index a4e2b0de3..826bb80bb 100644
--- a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
+++ b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
@@ -1,4 +1,4 @@
-import React, { useEffect } from 'react'
+import React, { useEffect, useState } from 'react'
 import PropTypes from 'prop-types'
 import { useDispatch, useSelector } from 'react-redux'
 import { fetchSttList } from '../../actions/sttList'
@@ -12,15 +12,19 @@ import ComboBox from '../ComboBox'
  * @param {function} handleBlur - Runs on blur of combo box element.
  * @param {function} error - Reference to stt errors object.
  */
+
 function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
   const sttList = useSelector((state) => state?.stts?.sttList)
   const dispatch = useDispatch()
+  const [numTries, setNumTries] = useState(0)
 
   useEffect(() => {
-    if (sttList.length === 0) {
+    if (sttList.length === 0 && numTries < 6) {
       dispatch(fetchSttList())
+      console.log('Num Tries: %d', numTries)
+      setNumTries(numTries + 1)
     }
-  }, [dispatch, sttList])
+  }, [dispatch, sttList, numTries])
 
   return (
     <ComboBox

From f8c6131ea663ac987dd79f3bd61639d2f94d0939 Mon Sep 17 00:00:00 2001
From: Eric Lipe <elipe@teamraft.com>
Date: Mon, 2 Oct 2023 12:12:02 -0600
Subject: [PATCH 2/6] - Adding error modal when stt list is empty

---
 .../components/STTComboBox/STTComboBox.jsx    | 78 ++++++++++++++-----
 1 file changed, 57 insertions(+), 21 deletions(-)

diff --git a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
index 826bb80bb..fa2092908 100644
--- a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
+++ b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
@@ -1,8 +1,9 @@
-import React, { useEffect, useState } from 'react'
+import React, { useEffect, useState, useRef } from 'react'
 import PropTypes from 'prop-types'
 import { useDispatch, useSelector } from 'react-redux'
-import { fetchSttList } from '../../actions/sttList'
+import { fetchSttList, EMPTY_STTS_LIST_ERROR } from '../../actions/sttList'
 import ComboBox from '../ComboBox'
+import Button from '../Button'
 
 /**
  * @param {function} selectStt - Function to reference and change the
@@ -17,35 +18,70 @@ function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
   const sttList = useSelector((state) => state?.stts?.sttList)
   const dispatch = useDispatch()
   const [numTries, setNumTries] = useState(0)
+  const [reachedMaxTries, setReachedMaxTries] = useState(false)
 
   useEffect(() => {
     if (sttList.length === 0 && numTries < 6) {
       dispatch(fetchSttList())
-      console.log('Num Tries: %d', numTries)
       setNumTries(numTries + 1)
+    } else {
+      setReachedMaxTries(true)
     }
   }, [dispatch, sttList, numTries])
 
+  const modalRef = useRef()
+  const headerRef = useRef()
+  const onSignOut = () => {
+    window.location.href = `${process.env.REACT_APP_BACKEND_URL}/logout/oidc`
+  }
+
   return (
-    <ComboBox
-      name="stt"
-      label="Associated State, Tribe, or Territory*"
-      error={error ? 'A state, tribe, or territory is required' : undefined}
-      handleSelect={selectStt}
-      selected={selectedStt}
-      handleBlur={handleBlur}
-      placeholder="- Select or Search -"
-      aria-required="true"
-    >
-      <option value="" disabled hidden>
-        - Select or Search -
-      </option>
-      {sttList.map((stt) => (
-        <option className="sttOption" key={stt.id} value={stt.name}>
-          {stt.name}
+    <>
+      <ComboBox
+        name="stt"
+        label="Associated State, Tribe, or Territory*"
+        error={error ? 'A state, tribe, or territory is required' : undefined}
+        handleSelect={selectStt}
+        selected={selectedStt}
+        handleBlur={handleBlur}
+        placeholder="- Select or Search -"
+        aria-required="true"
+      >
+        <option value="" disabled hidden>
+          - Select or Search -
         </option>
-      ))}
-    </ComboBox>
+        {sttList.map((stt) => (
+          <option className="sttOption" key={stt.id} value={stt.name}>
+            {stt.name}
+          </option>
+        ))}
+      </ComboBox>
+      <div
+        id="emptySttListModal"
+        className={`modal ${
+          reachedMaxTries ? 'display-block' : 'display-none'
+        }`}
+      >
+        <div className="modal-content" ref={modalRef}>
+          <h1
+            className="font-serif-xl margin-4 margin-bottom-0 text-normal"
+            tabIndex="-1"
+            ref={headerRef}
+          >
+            TDP systems are currently experiencing technical difficulties.
+          </h1>
+          <p className="margin-4 margin-top-1">
+            Please sign out and try signing in again. If the issue persists
+            contact support at tanfdata@acf.hhs.gov.
+          </p>
+          <div className="margin-x-4 margin-bottom-4">
+            <Button type="button" className="sign-out" onClick={onSignOut}>
+              Sign Out Now
+            </Button>
+          </div>
+        </div>
+      </div>
+    </>
   )
 }
 

From dd311ba88bce1636250b7cfdf5fe6248bc1cb7e2 Mon Sep 17 00:00:00 2001
From: Eric Lipe <elipe@teamraft.com>
Date: Tue, 3 Oct 2023 08:17:03 -0600
Subject: [PATCH 3/6] - Not defaulting to show error modal

---
 tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
index fa2092908..b25e05fec 100644
--- a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
+++ b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
@@ -1,7 +1,7 @@
 import React, { useEffect, useState, useRef } from 'react'
 import PropTypes from 'prop-types'
 import { useDispatch, useSelector } from 'react-redux'
-import { fetchSttList, EMPTY_STTS_LIST_ERROR } from '../../actions/sttList'
+import { fetchSttList } from '../../actions/sttList'
 import ComboBox from '../ComboBox'
 import Button from '../Button'
 
@@ -21,13 +21,13 @@ function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
   const [reachedMaxTries, setReachedMaxTries] = useState(false)
 
   useEffect(() => {
-    if (sttList.length === 0 && numTries < 6) {
+    if (sttList.length === 0 && numTries <= 5) {
       dispatch(fetchSttList())
       setNumTries(numTries + 1)
-    } else {
+    } else if (sttList.length === 0 && numTries > 5 && !reachedMaxTries) {
       setReachedMaxTries(true)
     }
-  }, [dispatch, sttList, numTries])
+  }, [dispatch, sttList, numTries, reachedMaxTries])
 
   const modalRef = useRef()
   const headerRef = useRef()

From 590afbbd4fec051dba4664a725163e19eabc570e Mon Sep 17 00:00:00 2001
From: Eric Lipe <elipe@teamraft.com>
Date: Tue, 3 Oct 2023 10:10:22 -0600
Subject: [PATCH 4/6] - Updated to use redux state instead of component state
 for request counting

---
 .../src/components/STTComboBox/STTComboBox.jsx   | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
index b25e05fec..24d39a19c 100644
--- a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
+++ b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
@@ -15,19 +15,23 @@ import Button from '../Button'
  */
 
 function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
-  const sttList = useSelector((state) => state?.stts?.sttList)
+  const sttReduction = useSelector((state) => state?.stts)
   const dispatch = useDispatch()
   const [numTries, setNumTries] = useState(0)
   const [reachedMaxTries, setReachedMaxTries] = useState(false)
 
   useEffect(() => {
-    if (sttList.length === 0 && numTries <= 5) {
+    if (sttReduction.sttList.length === 0 && numTries <= 5) {
       dispatch(fetchSttList())
-      setNumTries(numTries + 1)
-    } else if (sttList.length === 0 && numTries > 5 && !reachedMaxTries) {
+      if (!sttReduction.loading) setNumTries(numTries + 1)
+    } else if (
+      sttReduction.sttList.length === 0 &&
+      numTries > 5 &&
+      !reachedMaxTries
+    ) {
       setReachedMaxTries(true)
     }
-  }, [dispatch, sttList, numTries, reachedMaxTries])
+  }, [dispatch, sttReduction.sttList, numTries, reachedMaxTries])
 
   const modalRef = useRef()
   const headerRef = useRef()
@@ -50,7 +54,7 @@ function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
         <option value="" disabled hidden>
           - Select or Search -
         </option>
-        {sttList.map((stt) => (
+        {sttReduction.sttList.map((stt) => (
           <option className="sttOption" key={stt.id} value={stt.name}>
             {stt.name}
           </option>

From 9e99a1668d235e8b52261c5901249cf7cb752fed Mon Sep 17 00:00:00 2001
From: Eric Lipe <elipe@teamraft.com>
Date: Tue, 3 Oct 2023 10:20:26 -0600
Subject: [PATCH 5/6] - Simplifying if block

---
 .../src/components/STTComboBox/STTComboBox.jsx         | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
index 24d39a19c..266f9d0b8 100644
--- a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
+++ b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
@@ -21,12 +21,16 @@ function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
   const [reachedMaxTries, setReachedMaxTries] = useState(false)
 
   useEffect(() => {
-    if (sttReduction.sttList.length === 0 && numTries <= 5) {
+    if (
+      sttReduction.sttList.length === 0 &&
+      numTries <= 3 &&
+      !sttReduction.loading
+    ) {
       dispatch(fetchSttList())
-      if (!sttReduction.loading) setNumTries(numTries + 1)
+      setNumTries(numTries + 1)
     } else if (
       sttReduction.sttList.length === 0 &&
-      numTries > 5 &&
+      numTries > 3 &&
       !reachedMaxTries
     ) {
       setReachedMaxTries(true)

From 7b883c7ebef2f6e893cc294a3b6270e0abbaaf92 Mon Sep 17 00:00:00 2001
From: Eric Lipe <elipe@teamraft.com>
Date: Tue, 17 Oct 2023 15:09:23 -0600
Subject: [PATCH 6/6] - Updated to use our pre-built modal instead of
 re-inventing the wheel

---
 .../components/STTComboBox/STTComboBox.jsx    | 52 ++++++++-----------
 1 file changed, 21 insertions(+), 31 deletions(-)

diff --git a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
index 266f9d0b8..4f8adf0f2 100644
--- a/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
+++ b/tdrs-frontend/src/components/STTComboBox/STTComboBox.jsx
@@ -4,6 +4,7 @@ import { useDispatch, useSelector } from 'react-redux'
 import { fetchSttList } from '../../actions/sttList'
 import ComboBox from '../ComboBox'
 import Button from '../Button'
+import Modal from '../Modal'
 
 /**
  * @param {function} selectStt - Function to reference and change the
@@ -15,27 +16,27 @@ import Button from '../Button'
  */
 
 function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
-  const sttReduction = useSelector((state) => state?.stts)
+  const sttListRequest = useSelector((state) => state?.stts)
   const dispatch = useDispatch()
   const [numTries, setNumTries] = useState(0)
   const [reachedMaxTries, setReachedMaxTries] = useState(false)
 
   useEffect(() => {
     if (
-      sttReduction.sttList.length === 0 &&
+      sttListRequest.sttList.length === 0 &&
       numTries <= 3 &&
-      !sttReduction.loading
+      !sttListRequest.loading
     ) {
       dispatch(fetchSttList())
       setNumTries(numTries + 1)
     } else if (
-      sttReduction.sttList.length === 0 &&
+      sttListRequest.sttList.length === 0 &&
       numTries > 3 &&
       !reachedMaxTries
     ) {
       setReachedMaxTries(true)
     }
-  }, [dispatch, sttReduction.sttList, numTries, reachedMaxTries])
+  }, [dispatch, sttListRequest.sttList, numTries, reachedMaxTries])
 
   const modalRef = useRef()
   const headerRef = useRef()
@@ -58,37 +59,26 @@ function STTComboBox({ selectStt, selectedStt, handleBlur, error }) {
         <option value="" disabled hidden>
           - Select or Search -
         </option>
-        {sttReduction.sttList.map((stt) => (
+        {sttListRequest.sttList.map((stt) => (
           <option className="sttOption" key={stt.id} value={stt.name}>
             {stt.name}
           </option>
         ))}
       </ComboBox>
-      <div
-        id="emptySttListModal"
-        className={`modal ${
-          reachedMaxTries ? 'display-block' : 'display-none'
-        }`}
-      >
-        <div className="modal-content" ref={modalRef}>
-          <h1
-            className="font-serif-xl margin-4 margin-bottom-0 text-normal"
-            tabIndex="-1"
-            ref={headerRef}
-          >
-            TDP systems are currently experiencing technical difficulties.
-          </h1>
-          <p className="margin-4 margin-top-1">
-            Please sign out and try signing in again. If the issue persists
-            contact support at tanfdata@acf.hhs.gov.
-          </p>
-          <div className="margin-x-4 margin-bottom-4">
-            <Button type="button" className="sign-out" onClick={onSignOut}>
-              Sign Out Now
-            </Button>
-          </div>
-        </div>
-      </div>
+      <Modal
+        title="TDP systems are currently experiencing technical difficulties."
+        message="Please sign out and try signing in again. If the issue persists contact support at tanfdata@acf.hhs.gov."
+        isVisible={reachedMaxTries}
+        buttons={[
+          {
+            key: '1',
+            text: 'Sign Out Now',
+            onClick: () => {
+              onSignOut()
+            },
+          },
+        ]}
+      />
     </>
   )
 }