import { useState, useContext, useEffect } from "react"; import NewYorkCaption from "./captionHeaders/newYorkCaption.js"; import NewJerseyCaption from "./captionHeaders/newJerseyCaption.js"; import FloridaCaption from "./captionHeaders/floridaCaption.js"; import { useParams } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom"; import EditElement from "../../pageElements/EditElement"; import { db } from "../../firebase"; import { collection, updateDoc, onSnapshot, doc, getDoc, setDoc, increment, } from "firebase/firestore"; import { AppContext } from "../../Hooks/useContext/appContext"; import Button from "../../pageElements/Button"; import ConfirmModal from "../Modals/ConfirmModal"; import LoadingSpinner from "../../pageElements/LoadingSpinner"; import { docEditCopy } from "../../Constants/Copy/docEditCopy.js"; import "../../styles/docedit-page.scss"; const DocEditPage = () => { const { documentId, responseGenerations, caseId, documentType } = useParams(); const navigate = useNavigate(); const [parsedRogs, setParsedRogs] = useState(); const [responses, setResponses] = useState([1]); const [fetchedCase, setFetchedCase] = useState(); const [showInputEle, setShowInputEle] = useState(true); const [document, setDocument] = useState(null); const { appState } = useContext(AppContext); const { group } = appState; const appUserId = group ? group.appUserId : null; const [docId, setDocId] = useState(documentId); const [saveDocumentId, setSaveDocumentId] = useState(""); const [showSaveModal, setShowSaveModal] = useState(false); const [isLoading, setIsLoading] = useState(false); const [isReport, setIsReport] = useState(false); const [issueText, setIssueText] = useState(""); const [showErrorModal, setShowErrorModal] = useState(false); const [responsesCreated, setResponsesCreated] = useState( parseInt(responseGenerations) ); const [index, setIndex] = useState(0); const [isBusy, setIsBusy] = useState(false); // For document generation: const state = group.state[0] ? group.state[0].code : "ny"; const lawFirm = group ? group?.firm : null; const streetAdd = group ? group?.streetAddress : null; const city = group ? group.city : null; const usState = group.state[0] ? group.state[0].code : "ny"; const zipCode = group ? group.zipCode : null; const telephone = group ? group.telephone : null; const apiUrl = process.env.NODE_ENV === "development" ? process.env.REACT_APP_API_DEV : process.env.REACT_APP_API_PROD; const displayCopy = state === "ny" ? docEditCopy.NewYork : state === "nj" ? docEditCopy.NewJersey : docEditCopy.NewYork; const headerPicker = () => { switch (state) { case "ny": return ( ); case "nj": return ( ); case "fl": return ( ); default: return ( ); } }; const headerString = documentType === "interrogatories" ? ( "Response to Interrogatories" ) : documentType === "admissions" ? ( "Response to Request for Admissions" ) : documentType === "production" ? ( "Response to Request for Production" ) : documentType === "combined-numbered" ? ( "Response to Interrogatories and Request for Production" ) : ( <> ); const servingParty = fetchedCase?.clientPosition === "Defendant" ? fetchedCase?.plaintiffParties : fetchedCase?.defendantParties; const messages = [ "Generating responses. Please be patient, this may take several minutes.", ]; /* * GET docuement data from Firebase * */ useEffect(() => { if (!appUserId || !docId) { setDocument(null); return; } try { getCase(caseId); getDocument(); } catch (err) { console.log("Error:", err); } }, [appUserId, docId, caseId]); /* * GET parsed requests. * GET completions if already generated */ useEffect(() => { if (!documentId || !documentType) { return; } // TODO: possible *BUG* sometimes sends network req to gen repsonses after first (maybe state is not updating?) getParsedRequests(documentId, documentType); if (responsesCreated > 0) { getCompletions(documentId) .then((data) => { const resp = data[0].responses.map((item, index) => { // NEVER CHANGE THIS: return { showInputEle: false, resp: item.text, index: index }; }); setResponses(resp); }) .catch((err) => console.log(err)); } }, [documentId]); /* * If response completions = 0, generate responses */ useEffect(() => { if (responsesCreated > 0) { return; } if (responsesCreated < 1) { if (documentType == "combined-numbered") { try { const res = generateResponsesCombined(documentId); } catch (err) { console.log(err); } } else { try { const res = generateResponses(documentId); } catch (err) { console.log(err); } } } }, [responsesCreated, documentId]); async function getCase(parentCaseId) { try { const docRef = doc(db, "cases", `${parentCaseId}`); const docSnap = await getDoc(docRef); if (docSnap.exists()) { const _case = docSnap.data(); _case.id = docSnap._key.path.segments[1]; setFetchedCase(_case); } else { console.log("DB item does not exist"); } } catch (error) { console.log(`A system error has occurred: ${error}`); } } function getDocument() { const docRef = doc(db, "documents", `${docId}`); const unsub = onSnapshot(docRef, (snapshot) => { if (snapshot.exists() && snapshot.data().ownerId === appUserId) { setDocument({ ...snapshot.data(), documentId: snapshot.id }); } else { setDocument(null); } }); return unsub; } async function getParsedRequests(documentId) { if (documentId) { const docType = String(documentType); try { const response = await fetch( `${apiUrl}/getParsedRequests/${documentId}/${docType}`, { method: "GET", } ); const res = await response.json(); const req = res[0].requests; if (req.length > 1) { setParsedRogs(req); } } catch (err) { console.log("Error occured:", err); } } } async function getCompletions(docId) { const docType = String(documentType); const response = await fetch(`${apiUrl}/completions/${docId}/${docType}`, { method: "GET", }); const req = await response.json(); return req; } async function generateResponsesCombined(documentId) { if (responsesCreated > 0) { return; } const docType = String(documentType); let mode; //TODO: remove isRequests var if not goign to use const isRequests = false; try { setIsLoading(true); fetch( `${apiUrl}/genResponseFromArrayCombined/${documentId}/${docType}/${isRequests}`, { method: "GET", } ) .then(function (response) { return response.json(); }) .then((data) => { console.log("data in genResponseFromArrayCombined", data); const respArray = data[0].responses; const result = respArray?.map((item, index) => { let obj = {}; obj["showInputEle"] = false; obj["resp"] = item.text; obj["index"] = index; return obj; }); setResponses(result); updateRespGenerationCount(documentId); setIsLoading(false); }) .catch((err) => console.log(err)); } catch (err) { console.log("err", err); } } async function generateResponses(documentId) { if (responsesCreated > 0) { return; } const docType = String(documentType); let mode; //TODO: remove isRequests var const isRequests = false; try { setIsLoading(true); fetch( `${apiUrl}/genResponseFromArray/${documentId}/${docType}/${isRequests}`, { method: "GET", } ) .then(function (response) { return response.json(); }) .then((data) => { const respArray = data[0].responses; const result = respArray?.map((item, index) => { let obj = {}; obj["showInputEle"] = false; obj["resp"] = item.text; obj["index"] = index; return obj; }); setResponses(result); updateRespGenerationCount(documentId); setIsLoading(false); }) .catch((err) => console.log(err)); } catch (err) { console.log("err", err); } } async function postEditedResponses() { let obj = {}; obj["type"] = documentType; obj["id"] = docId; obj["requests"] = responses; const data = JSON.stringify(obj); try { const response = await fetch(`${apiUrl}/storecompletions`, { method: "POST", headers: { "Content-Type": "application/json" }, json: true, body: data, }); const res = response; return res; } catch (error) { console.error("Error sending responses to the server:", error); } } async function createAndReturnDocx() { function stopBusy() { setIsBusy(false); } window.scrollTo({ top: 0 }); setIsBusy(true); const response = await handleCreateDocx(); if (response.status === 200) { setTimeout(getDocx, 5000); setTimeout(stopBusy, 2500); setTimeout(cleanUpDocx, 10000); } else { setShowErrorModal(true); } } async function cleanUpDocx() { const docId = documentId; const reqType = documentType; fetch(`${apiUrl}/cleanUpDocx/${docId}/${reqType}`, { method: "GET", }) .then((response) => { console.log(response); }) .catch((err) => { console.log(err); }); } async function getDocx() { const docId = documentId; const reqType = documentType; fetch(`${apiUrl}/getDocx/${docId}/${reqType}`, { method: "GET", }).then((response) => { response.blob().then((blob) => { let url = window.URL.createObjectURL(blob); let a = window.document.createElement("a"); a.href = url; a.download = `${reqType}-repsonse.docx`; a.click(); }); }); } async function handleCreateDocx() { // TODO: compare to see if any changes made before gen, save those const docId = documentId; const leadAttorneys = fetchedCase?.leadAttorneys ? fetchedCase?.leadAttorneys : null; const reqType = documentType; const captionOne = fetchedCase.caption; const captionTwo = fetchedCase.captionTwo; const caseNum = fetchedCase.caseNumber; const plaintiffs = fetchedCase.plaintiffParties; const defendants = fetchedCase.defendantParties; const venued = fetchedCase.venue; const juris = fetchedCase.jurisdiction; const judge = fetchedCase.judge; const clientPosition = fetchedCase?.clientPosition ? fetchedCase?.clientPosition : null; try { const response = await fetch(`${apiUrl}/genDocx/${docId}/${reqType}`, { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json", }, body: JSON.stringify({ caseCaption1: captionOne, caseCaption2: captionTwo, caseNumber: caseNum, clientPosition: clientPosition, defendant: defendants, firm: lawFirm, firmCity: city, firmState: usState.code, firmStreetAddress: streetAdd, firmZip: zipCode, judge: judge, jurisdiction: juris, leadAttorneys: leadAttorneys, plaintiff: plaintiffs, state: state, tel: telephone, venue: venued, }), }); return response; } catch (error) { console.error("Error sending responses to the server:", error); } } async function updateRespGenerationCount(docId) { await updateDoc(doc(db, "documents", docId), { responseGenerations: increment(1), }); setResponsesCreated((responsesCreated) => responsesCreated + 1); } function saveDocument(documentId) { setSaveDocumentId(documentId); setShowSaveModal(!showSaveModal); } async function postEditedResponses() { let obj = {}; obj["type"] = "INTERROGATORY"; obj["id"] = docId; obj["requests"] = responses; const data = JSON.stringify(obj); try { const response = await fetch(`${apiUrl}/storeeditedcompletions`, { method: "POST", headers: { "Content-Type": "application/json" }, json: true, body: data, }); const res = response; return res; } catch (error) { console.error("Error sending responses to the server:", error); } } const handleBlur = (e, i) => { const newSelectedResponses = responses?.map((r) => { if (r.index === i) { return { ...r, showInputEle: !showInputEle, }; } return r; }); setResponses(newSelectedResponses); }; const handleFocus = (arg, i) => { const newSelectedResponses = responses?.map((r) => { if (r.index === i) { return { ...r, showInputEle: !showInputEle, }; } return r; }); setResponses(newSelectedResponses); }; const handleEditValue = (e, i) => { const editingRes = responses?.map((r) => { if (r.index === i) { return { ...r, resp: e.target.value, }; } return r; }); setResponses(editingRes); }; const handleBack = () => { navigate(`/documents`); }; const handleCancelSave = () => { setShowSaveModal(false); }; const handleSave = () => { postEditedResponses(); setShowSaveModal(false); }; const handleConfirmSave = () => { setShowSaveModal(true); }; const handleReport = () => { setShowSaveModal(false); setIsReport(false); }; const handleConfirmReport = () => { setShowSaveModal(true); setIsReport(true); }; async function reportDoc() { const data = { documentId: documentId, caseId: caseId, appUserId: appUserId, issueDescription: issueText, }; try { const reportRef = collection(db, "supportrequests"); await setDoc(doc(reportRef, documentId), data); } catch (err) { console.log("Error saving case to db:", err); } } const onScrollClick = () => { const bottom = window.document.scrollingElement.scrollHeight; const place = window.scrollY; if (place > bottom / 2) { window.scrollTo({ top: 0, behavior: "smooth" }); } else if (place < bottom / 2) { window.scrollTo({ top: bottom, behavior: "smooth" }); } }; const numberingContent = (i) => { let numText; if (documentType === "interrogatories") { numText = "INTERROGATORY NO.."; } else if (documentType === "admissions") { numText = "REQUEST FOR ADMISSION NO."; } else if (documentType === "production") { numText = "REQUEST FOR PRODUCTION NO."; } else { numText = "REQUEST NO."; } return
{`${numText}${i + 1} `}
; }; const respondent = fetchedCase?.clientPosition == "Defendant" ? fetchedCase?.defendantParties : fetchedCase?.plaintiffParties; console.log("parsedRogs", parsedRogs); console.log("responses", responses); const editingContent = () => { return ( <>
{headerPicker()}
{headerString}
{displayCopy.prelimaryStatement( documentType, respondent, servingParty )}
{parsedRogs?.map((rog, i) => (
{numberingContent(i)} {rog?.text}
2 ? // NEVER CHANGE THIS responses[i].resp : null } setShowInputEle={setShowInputEle} showInputEle={ responses && responses.length > 2 ? responses[i].showInputEle : null } handleFocus={handleFocus} handleEditValue={handleEditValue} handleBlur={handleBlur} i={i} />
))}
handleConfirmReport()} >
Report an issue
{/* TODO: add tooltip: "This will save the document and create a .docx file that will (be downloaded? saved somewhere?" */}
{showSaveModal && !isReport && documentId !== null ? ( ) : null} {showSaveModal && isReport && documentId !== null ? ( ) : null} {showErrorModal ? ( setShowErrorModal(false)} onConfirm={() => setShowErrorModal(false)} buttonLabelText="Confirm" modalText={ "There was a problem. Support was notified and will respond within 24 hours." } /> ) : null} ); }; const readyToEdit = fetchedCase && responses.length > 1; return isLoading ? ( ) : isBusy ? ( ) : readyToEdit ? ( editingContent() ) : (

{" "} Response content for this document cannot be displayed at this time.

Support has been notified and will respond within 24 hours.

Return to Dashboard
); }; export default DocEditPage;