328 lines
9.7 KiB
JavaScript
328 lines
9.7 KiB
JavaScript
import React, { useState, useContext, useEffect, useRef } from "react";
|
|
import { CaseCard } from "../../pageElements/Cards.js";
|
|
import { Link, useNavigate, createSearchParams } from "react-router-dom";
|
|
import MobileContent from "../MobileContent";
|
|
import {
|
|
ArrowRight,
|
|
Activity,
|
|
FileEarmarkText,
|
|
Pencil,
|
|
Clock,
|
|
} from "react-bootstrap-icons";
|
|
import { db } from "../../firebase.js";
|
|
import {
|
|
collection,
|
|
doc,
|
|
setDoc,
|
|
onSnapshot,
|
|
query,
|
|
where,
|
|
} from "firebase/firestore";
|
|
import { Typeahead } from "react-bootstrap-typeahead";
|
|
import { AppContext } from "../../Hooks/useContext/appContext.js";
|
|
import UploadModal from "../Modals/UploadModal.js";
|
|
import Button from "react-bootstrap/Button";
|
|
import { getAuth } from "firebase/auth";
|
|
|
|
const Dashboard = () => {
|
|
const size = window.innerWidth < 440;
|
|
const [isMobile, setIsMobile] = useState(size);
|
|
const auth = getAuth();
|
|
const count = useRef(null);
|
|
const navigate = useNavigate();
|
|
const [allCases, setAllCases] = useState(null);
|
|
const [selectedCase, setSelectedCase] = useState(null);
|
|
const [showModal, setShowModal] = useState();
|
|
const [docCount, setDocCount] = useState();
|
|
const [isPromoFirstLogin, setIsPromoFirstLogin] = useState(true);
|
|
const [responseCount, setResponseCount] = useState();
|
|
const { appState } = useContext(AppContext);
|
|
const { group } = appState;
|
|
const appUserId = group ? group.appUserId : null;
|
|
const _fbAuthUid = group ? group.fbAuthUid : null;
|
|
const isDashboard = true;
|
|
|
|
useEffect(() => {
|
|
if (count.current == null) {
|
|
setIsMobile(window.innerWidth < 440);
|
|
}
|
|
if (count.current < 3) {
|
|
setIsMobile(window.innerWidth < 440);
|
|
}
|
|
return () => {
|
|
const temp = (count.current = count.current + 1);
|
|
count.current = temp;
|
|
};
|
|
}, []);
|
|
|
|
function getCases() {
|
|
if (!appUserId) {
|
|
setAllCases([]);
|
|
return;
|
|
}
|
|
const q = query(collection(db, "cases"), where("ownerId", "==", appUserId));
|
|
const unsub = onSnapshot(q, (snapshot) => {
|
|
const data = snapshot.docs.map((doc) => doc.data());
|
|
data.sort((a, b) => {
|
|
return a.filedDate < b.filedDate ? 1 : -1;
|
|
});
|
|
setAllCases(data);
|
|
});
|
|
return unsub;
|
|
}
|
|
|
|
function getStats() {
|
|
if (!appUserId) {
|
|
return;
|
|
}
|
|
const q = query(
|
|
collection(db, "documents"),
|
|
where("ownerId", "==", appUserId)
|
|
);
|
|
const unsub = onSnapshot(q, (snapshot) => {
|
|
const data = snapshot.docs.map((doc) => doc.data());
|
|
if (data) {
|
|
setDocCount(data?.length);
|
|
const respCount = data?.reduce(function (acc, obj) {
|
|
return acc + obj.responseGenerations;
|
|
}, 0);
|
|
setResponseCount(respCount);
|
|
}
|
|
});
|
|
return unsub;
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!appUserId) {
|
|
return;
|
|
}
|
|
const unsubCases = getCases();
|
|
const unsubStats = getStats();
|
|
return () => {
|
|
typeof unsubCases !== "undefined" && unsubCases();
|
|
typeof unsubStats !== "undefined" && unsubStats();
|
|
};
|
|
}, [appUserId]);
|
|
|
|
const handleViewClick = (caseId) => {
|
|
navigate(`/casedetails/${caseId}`);
|
|
};
|
|
|
|
if (!group) {
|
|
return null;
|
|
}
|
|
|
|
async function handleClick(e) {
|
|
e.preventDefault();
|
|
|
|
const updateRef = collection(db, "users");
|
|
await setDoc(doc(updateRef, _fbAuthUid), {
|
|
isPromotionalFirstLogin: false,
|
|
});
|
|
navigate({
|
|
pathname: "/passwordreset/",
|
|
search: `?${createSearchParams({
|
|
mode: "enterEmail",
|
|
})}`,
|
|
});
|
|
}
|
|
|
|
const DesktopContent = () => {
|
|
return allCases !== null ? (
|
|
<div>
|
|
<div className="dashboard-filter mb-3">
|
|
<Typeahead
|
|
className="flex-grow-1"
|
|
id="case-search"
|
|
labelKey="caseNumber"
|
|
options={allCases}
|
|
minLength={1}
|
|
placeholder="Search by Case Number"
|
|
onChange={(selected) => {
|
|
let item = null;
|
|
for (const currentItem of selected) {
|
|
item = { ...currentItem };
|
|
}
|
|
setSelectedCase(item);
|
|
}}
|
|
/>
|
|
<Button
|
|
disabled={selectedCase === null}
|
|
onClick={() => handleViewClick(selectedCase?.caseId)}
|
|
>
|
|
View Case
|
|
</Button>
|
|
<Button
|
|
disabled={selectedCase === null}
|
|
onClick={() => setShowModal(true)}
|
|
>
|
|
Express Document Upload
|
|
</Button>
|
|
</div>
|
|
{allCases.slice(0, 3).map((c, i) => (
|
|
<CaseCard
|
|
key={`linkcard-${i}`}
|
|
caption={c.caption}
|
|
captionTwo={c.captionTwo}
|
|
jurisdiction={c.jurisdiction}
|
|
caseNumber={`Index no. ${c.caseNumber}`}
|
|
filedDate={c.filedDate}
|
|
caseId={c.caseId}
|
|
labelText="View"
|
|
onClick={handleViewClick}
|
|
/>
|
|
))}
|
|
{allCases?.length > 3 ? (
|
|
<div className="view-all-link-box mb-3">
|
|
<div className="view-all-wrapper">
|
|
<Link className="view-all-link" to="/cases">
|
|
View All{" "}
|
|
<span className="arrow-wrapper">
|
|
<ArrowRight />
|
|
</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
) : null;
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="dashboard-header">
|
|
<h2 className="doc-header-text">
|
|
{!!(group.firstName && group.lastName) ? (
|
|
<span>
|
|
{group.firstName} {group.lastName}
|
|
</span>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</h2>
|
|
<div className="user-name-container2">{group.firm}</div>
|
|
</div>
|
|
<div className="app-divider dash-divider" />
|
|
{isPromoFirstLogin ? (
|
|
<>
|
|
<div className="dash-promo-first-box">
|
|
<div className="dash-promo-first-wrap">
|
|
<div className="dash-promo-first-textwrap">
|
|
<div className="dash-promo-first-text">
|
|
<p className="dash-welcome-text">
|
|
Welcome to Novodraft, attorney {group.lastName}. We are
|
|
excited to introduce you to our application. Review the
|
|
step-by-step user guide by clicking "How-to" in the above
|
|
navigation bar.
|
|
</p>
|
|
<p className="dash-welcome-text">
|
|
Your login is username: <strong>{group.email}</strong> with
|
|
a temporary password: <strong>{group.tpe}</strong>. You
|
|
should change your password now by{" "}
|
|
<span onClick={handleClick} className="dash-clicknow-span">
|
|
clicking here
|
|
</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="app-divider dash-divider" />
|
|
</>
|
|
) : null}
|
|
<div className="stats-container">
|
|
<div className="stats-row-box">
|
|
<div className="stats-unit-wrapper">
|
|
<div className="stats-icon-wrapper">
|
|
<Activity style={{ color: "#ff6200" }} />
|
|
</div>
|
|
{allCases?.length >= 1 ? (
|
|
<div>
|
|
<p className="stats-text">
|
|
{allCases?.length === 1
|
|
? `${allCases?.length} active case`
|
|
: `${allCases?.length} active cases`}
|
|
</p>
|
|
</div>
|
|
) : (
|
|
<div>
|
|
<p className="stats-text">
|
|
{allCases?.length} active cases - Click on the "Cases" tab,
|
|
above, and create a case to get started.
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="stats-unit-wrapper">
|
|
{allCases?.length >= 1 ? (
|
|
<>
|
|
<div className="stats-icon-wrapper">
|
|
<FileEarmarkText style={{ color: "#6da8dc" }} />
|
|
</div>
|
|
<div>
|
|
<p className="stats-text">
|
|
{docCount === 1
|
|
? `${docCount} document uploaded`
|
|
: `${docCount} documents uploaded`}
|
|
</p>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</div>
|
|
{responseCount > 0 ? (
|
|
<>
|
|
<div className="stats-unit-wrapper">
|
|
<div className="stats-icon-wrapper">
|
|
<Pencil style={{ color: "#767676" }} />
|
|
</div>
|
|
<div>
|
|
<p className="stats-text">
|
|
{responseCount}
|
|
{responseCount < 2
|
|
? " response Novodrafted"
|
|
: " responses Novodrafted"}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<></>
|
|
)}
|
|
|
|
{responseCount > 0 ? (
|
|
<>
|
|
<div className="stats-unit-wrapper">
|
|
<div className="stats-icon-wrapper">
|
|
<Clock style={{ color: "#ff6200" }} />
|
|
</div>
|
|
<div>
|
|
<p className="stats-text">
|
|
{Math.round(responseCount * 3.1799 * 10) / 10} hours saved
|
|
using Novodraft
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</div>
|
|
</div>
|
|
{isMobile ? (
|
|
<MobileContent isDashboard={isDashboard} />
|
|
) : (
|
|
<DesktopContent />
|
|
)}
|
|
{showModal && selectedCase !== null ? (
|
|
<UploadModal setShowModal={setShowModal} caseData={selectedCase} />
|
|
) : null}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Dashboard;
|