diff --git a/src/components/Header/components/NavbarDesktop.tsx b/src/components/Header/components/NavbarDesktop.tsx
index 41f236ed..d94eac78 100644
--- a/src/components/Header/components/NavbarDesktop.tsx
+++ b/src/components/Header/components/NavbarDesktop.tsx
@@ -93,7 +93,7 @@ const LiSection = styled("li")({
color: "#585C65",
fontFamily: "poppins",
fontSize: "17px",
- fontWeight: 700,
+ fontWeight: 600,
lineHeight: "40px",
letterSpacing: "normal",
textDecoration: "none",
@@ -181,7 +181,7 @@ const LiSection = styled("li")({
color: "#FFFFFF",
fontFamily: "poppins",
fontSize: "17px",
- fontWeight: 700,
+ fontWeight: 600,
lineHeight: "40px",
letterSpacing: "normal",
textDecoration: "none",
diff --git a/src/components/Header/USABanner.tsx b/src/components/Header/components/USABanner.tsx
similarity index 89%
rename from src/components/Header/USABanner.tsx
rename to src/components/Header/components/USABanner.tsx
index 1e0be921..f0a364b7 100644
--- a/src/components/Header/USABanner.tsx
+++ b/src/components/Header/components/USABanner.tsx
@@ -1,6 +1,6 @@
import React from "react";
import { styled } from "@mui/material";
-import { headerData } from "../../config/globalHeaderData";
+import { headerData } from "../../../config/globalHeaderData";
const BannerArea = styled("div")({
flexDirection: "row",
@@ -35,7 +35,7 @@ const BannerContainer = styled("div")({
});
const USABanner = () => (
-
+
An official website of the United States government
diff --git a/src/components/Header/index.test.tsx b/src/components/Header/index.test.tsx
index 9f70710b..f6c01303 100644
--- a/src/components/Header/index.test.tsx
+++ b/src/components/Header/index.test.tsx
@@ -1,22 +1,30 @@
import { FC, useMemo } from "react";
import { BrowserRouter } from "react-router-dom";
import { axe } from "jest-axe";
-import { render } from "@testing-library/react";
+import { render, waitFor } from "@testing-library/react";
import { MockedProvider } from "@apollo/client/testing";
import Header from "./index";
import { ContextState, Context, Status } from "../Contexts/AuthContext";
-const Parent: FC<{ children: React.ReactElement; loggedIn: boolean }> = ({
+const mockUseMediaQuery = jest.fn();
+jest.mock("@mui/material", () => ({
+ ...jest.requireActual("@mui/material"),
+ useMediaQuery: (query: string) => mockUseMediaQuery(query),
+}));
+
+const Parent: FC<{ children: React.ReactElement; loggedIn?: boolean; error?: string }> = ({
children,
- loggedIn,
+ loggedIn = false,
+ error = null,
}) => {
const value: ContextState = useMemo(
() => ({
isLoggedIn: loggedIn,
- status: Status.LOADED,
+ status: error ? Status.ERROR : Status.LOADED,
user: null,
+ error,
}),
- [loggedIn]
+ [loggedIn, error]
);
return (
@@ -28,26 +36,74 @@ const Parent: FC<{ children: React.ReactElement; loggedIn: boolean }> = ({
);
};
-describe("should not have any accessibility violations", () => {
- it("when logged in", async () => {
- const { container } = render(
-
-
-
- );
- const results = await axe(container);
+describe("Accessibility", () => {
+ it("should not have accessibility violations (Logged In)", async () => {
+ const { container } = render(, { wrapper: (p) => });
+
+ expect(await axe(container)).toHaveNoViolations();
+ });
+
+ it("should not have accessibility violations (Logged Out)", async () => {
+ const { container } = render(, {
+ wrapper: (p) => ,
+ });
+
+ expect(await axe(container)).toHaveNoViolations();
+ });
+});
+
+describe("Implementation Requirements", () => {
+ it("should show the desktop header when the screen is larger than 1024px", () => {
+ mockUseMediaQuery.mockReturnValue(false);
+
+ const { getByTestId } = render(, {
+ wrapper: (p) => ,
+ });
+
+ expect(getByTestId("navigation-header-desktop")).toBeInTheDocument();
+ });
+
+ it("should show the tablet and mobile header when the screen is 1024px or smaller", () => {
+ mockUseMediaQuery.mockReturnValue(true);
+
+ const { getByTestId } = render(, {
+ wrapper: (p) => ,
+ });
+
+ expect(getByTestId("navigation-header-mobile")).toBeInTheDocument();
+ });
+
+ it("should always show the USA banner", () => {
+ const { getByTestId } = render(, {
+ wrapper: (p) => ,
+ });
+
+ expect(getByTestId("navigation-flag-banner")).toBeInTheDocument();
+ });
+
+ it("should show an error snackbar when there is an authentication error", async () => {
+ render(, {
+ wrapper: (p) => ,
+ });
- expect(results).toHaveNoViolations();
+ await waitFor(() => {
+ expect(global.mockEnqueue).toHaveBeenCalledWith("mock auth error", {
+ variant: "error",
+ });
+ });
});
- it("when logged out", async () => {
- const { container } = render(
-
-
-
- );
- const results = await axe(container);
+ it("should show an error snackbar when there is an unknown error type", async () => {
+ render(, {
+ wrapper: (p) => (
+
+ ),
+ });
- expect(results).toHaveNoViolations();
+ await waitFor(() => {
+ expect(global.mockEnqueue).toHaveBeenCalledWith("An unknown error occurred during login", {
+ variant: "error",
+ });
+ });
});
});
diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx
index efee2084..2cb51d6d 100644
--- a/src/components/Header/index.tsx
+++ b/src/components/Header/index.tsx
@@ -1,34 +1,34 @@
-import { useState, useEffect } from "react";
+import { useEffect } from "react";
import { useMediaQuery } from "@mui/material";
-import HeaderDesktop from "./HeaderDesktop";
-import HeaderTabletAndMobile from "./HeaderTabletAndMobile";
-import USABanner from "./USABanner";
-import GenericAlert from "../GenericAlert";
+import { useSnackbar } from "notistack";
+import HeaderDesktop from "./components/HeaderDesktop";
+import HeaderTabletAndMobile from "./components/HeaderTabletAndMobile";
+import USABanner from "./components/USABanner";
import { useAuthContext } from "../Contexts/AuthContext";
const Header = () => {
+ const { enqueueSnackbar } = useSnackbar();
+ const { error: authError } = useAuthContext();
const tabletAndMobile = useMediaQuery("(max-width: 1024px)");
- const [showLoginError, setShowLoginError] = useState(false);
- const authContext = useAuthContext();
-
useEffect(() => {
- if (authContext.error !== undefined) {
- setShowLoginError(true);
- setTimeout(() => setShowLoginError(false), 10000);
+ if (!authError) {
+ return;
}
- }, [authContext]);
+
+ enqueueSnackbar(
+ typeof authError === "string" && authError?.length > 0
+ ? authError
+ : "An unknown error occurred during login",
+ { variant: "error" }
+ );
+ }, [authError]);
return (
- <>
-
- {authContext.error}
-
-
-
- {tabletAndMobile ? : }
-
- >
+
+
+ {tabletAndMobile ? : }
+
);
};
diff --git a/src/components/HistoryDialog/index.test.tsx b/src/components/HistoryDialog/index.test.tsx
new file mode 100644
index 00000000..3d9eb7bf
--- /dev/null
+++ b/src/components/HistoryDialog/index.test.tsx
@@ -0,0 +1,169 @@
+import { axe } from "jest-axe";
+import { render, within } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
+import HistoryDialog, { IconType } from "./index";
+
+type MockStatuses = "uploaded" | "downloaded" | "error";
+
+const IconMap: IconType = {
+ uploaded: "upload",
+ downloaded: "download",
+ error: "error",
+};
+
+const BaseProps: React.ComponentProps = {
+ open: true,
+ preTitle: "",
+ title: "",
+ history: [],
+ iconMap: IconMap,
+ getTextColor: () => "red",
+ onClose: () => {},
+};
+
+describe("Accessibility", () => {
+ it("should have no violations", async () => {
+ const { container } = render();
+
+ expect(await axe(container)).toHaveNoViolations();
+ });
+});
+
+describe("Basic Functionality", () => {
+ it("should render without crashing", () => {
+ expect(() => render()).not.toThrow();
+ });
+
+ it("should close the dialog when the 'Close' button is clicked", () => {
+ const onClose = jest.fn();
+ const { getByTestId } = render();
+
+ userEvent.click(getByTestId("history-dialog-close"));
+
+ expect(onClose).toHaveBeenCalledTimes(1);
+ });
+
+ it("should close the dialog when the backdrop is clicked", () => {
+ const onClose = jest.fn();
+ const { getAllByRole } = render();
+
+ userEvent.click(getAllByRole("presentation")[1]);
+
+ expect(onClose).toHaveBeenCalledTimes(1);
+ });
+
+ it("should render the correct title", () => {
+ const title = "This is a Test Title";
+ const { getByTestId } = render();
+
+ expect(within(getByTestId("history-dialog")).getByText(title)).toBeInTheDocument();
+ });
+
+ it("should render the correct pre-title", () => {
+ const preTitle = "This is a Test Pre-Title";
+ const { getByTestId } = render();
+
+ expect(within(getByTestId("history-dialog")).getByText(preTitle)).toBeInTheDocument();
+ });
+
+ it("should call getTextColor with the correct status", () => {
+ const getTextColor = jest.fn();
+ const history: HistoryBase[] = [
+ { status: "uploaded", dateTime: new Date().toISOString(), userID: "test", reviewComment: "" },
+ ];
+
+ render();
+
+ expect(getTextColor).toHaveBeenCalledWith("uploaded");
+ });
+});
+
+describe("Implementation Requirements", () => {
+ it("should sort the history by date in descending order", () => {
+ const history: HistoryBase[] = [
+ { status: "error", dateTime: "2022-05-19T04:12:00Z", userID: "test", reviewComment: "" }, // 1
+ { status: "uploaded", dateTime: "2022-03-20T14:45:00Z", userID: "test", reviewComment: "" }, // 3
+ { status: "downloaded", dateTime: "2022-04-25T11:56:00Z", userID: "test", reviewComment: "" }, // 2
+ ];
+
+ const { getByTestId } = render();
+
+ expect(
+ within(getByTestId("history-item-0")).getByTestId("history-item-0-status")
+ ).toHaveTextContent(/error/i);
+
+ expect(
+ within(getByTestId("history-item-1")).getByTestId("history-item-1-status")
+ ).toHaveTextContent(/downloaded/i);
+
+ expect(
+ within(getByTestId("history-item-2")).getByTestId("history-item-2-status")
+ ).toHaveTextContent(/uploaded/i);
+ });
+
+ it("should render the parsed date for each history item", () => {
+ const history: HistoryBase[] = [
+ { status: "uploaded", dateTime: "2022-03-20T14:45:00Z", userID: "test", reviewComment: "" },
+ ];
+
+ const { getByTestId } = render();
+
+ expect(
+ within(getByTestId("history-item-0")).getByTestId("history-item-0-date")
+ ).toHaveTextContent("3/20/2022");
+ });
+
+ it("should render corresponding icon for the first history item", () => {
+ const history: HistoryBase[] = [
+ { status: "uploaded", dateTime: "2022-03-20T14:45:00Z", userID: "test", reviewComment: "" },
+ { status: "downloaded", dateTime: "2019-09-05T11:56:00Z", userID: "test", reviewComment: "" },
+ ];
+
+ const { getByTestId, queryByTestId } = render(
+
+ );
+
+ expect(getByTestId("history-item-0-icon")).toBeInTheDocument();
+ expect(getByTestId("history-item-0-icon")).toHaveAttribute("src", IconMap.uploaded);
+
+ expect(queryByTestId("history-item-1-icon")).not.toBeInTheDocument();
+ });
+
+ it("should render the status for each history item in uppercase", () => {
+ const history: HistoryBase[] = [
+ { status: "uploaded", dateTime: "2024-09-05T14:45:00Z", userID: "test", reviewComment: "" },
+ ];
+
+ const { getByTestId } = render();
+
+ expect(
+ within(getByTestId("history-item-0")).getByTestId("history-item-0-status")
+ ).toHaveTextContent(/UPLOADED/);
+ });
+
+ it("should have the unparsed date as a title attribute on the date element", () => {
+ const history: HistoryBase[] = [
+ { status: "uploaded", dateTime: "2024-09-05T14:45:00Z", userID: "test", reviewComment: "" },
+ ];
+
+ const { getByTestId } = render();
+
+ expect(
+ within(getByTestId("history-item-0")).getByTestId("history-item-0-date")
+ ).toHaveAttribute("title", "2024-09-05T14:45:00Z");
+ });
+
+ it("should fallback to #FFF if getTextColor is not a function", () => {
+ const history: HistoryBase[] = [
+ { status: "uploaded", dateTime: "2024-09-05T14:45:00Z", userID: "test", reviewComment: "" },
+ ];
+
+ const { getByTestId } = render(
+
+ );
+
+ expect(within(getByTestId("history-item-0")).getByTestId("history-item-0-status")).toHaveStyle({
+ color: "#FFF",
+ });
+ });
+});
diff --git a/src/components/Shared/HistoryDialog.tsx b/src/components/HistoryDialog/index.tsx
similarity index 96%
rename from src/components/Shared/HistoryDialog.tsx
rename to src/components/HistoryDialog/index.tsx
index 4bbe5414..26162357 100644
--- a/src/components/Shared/HistoryDialog.tsx
+++ b/src/components/HistoryDialog/index.tsx
@@ -150,9 +150,6 @@ const StyledTypography = styled(Typography)<{ color: CSSProperties["color"] }>((
const StyledAvatar = styled(Avatar)({
background: "transparent",
marginRight: "8px",
- "&.MuiAvatar-root": {
- marginLeft: "auto",
- },
});
const StyledCloseButton = styled(Button)({
@@ -215,7 +212,7 @@ const HistoryDialog = ({
{sortedHistory?.map(({ status, dateTime }, index) => (
@@ -226,13 +223,13 @@ const HistoryDialog = ({
{FormatDate(dateTime, "M/D/YYYY", "N/A")}
{status?.toString()?.toUpperCase()}
@@ -254,7 +251,7 @@ const HistoryDialog = ({
onClose()}
+ onClick={onClose}
variant="outlined"
size="large"
aria-label="Close dialog"
diff --git a/src/components/StatusBar/StatusBar.test.tsx b/src/components/StatusBar/StatusBar.test.tsx
index 0652b732..c503c72a 100644
--- a/src/components/StatusBar/StatusBar.test.tsx
+++ b/src/components/StatusBar/StatusBar.test.tsx
@@ -7,7 +7,7 @@ import StatusBar from "./StatusBar";
import StatusApproved from "../../assets/history/submissionRequest/StatusApproved.svg";
import StatusRejected from "../../assets/history/submissionRequest/StatusRejected.svg";
import { FormatDate } from "../../utils";
-import { HistoryIconMap } from "../../assets/history/submissionRequest";
+import { HistoryIconMap } from "./components/SubmissionRequestIconMap";
type Props = {
data: object;
@@ -372,8 +372,8 @@ describe("StatusBar > History Modal Tests", () => {
fireEvent.click(getByText("Full History"));
- expect(getByTestId("status-bar-history-item-0-icon")).toBeVisible();
- expect(() => getByTestId("status-bar-history-item-1-icon")).toThrow();
+ expect(getByTestId("history-item-0-icon")).toBeVisible();
+ expect(() => getByTestId("history-item-1-icon")).toThrow();
});
it.each(Object.entries(HistoryIconMap))(
@@ -387,7 +387,7 @@ describe("StatusBar > History Modal Tests", () => {
fireEvent.click(getByText("Full History"));
- const icon = getByTestId("status-bar-history-item-0-icon");
+ const icon = getByTestId("history-item-0-icon");
expect(icon).toBeVisible();
expect(icon).toHaveAttribute("alt", `${status} icon`);
@@ -418,7 +418,7 @@ describe("StatusBar > History Modal Tests", () => {
expect(queryByTestId("status-bar-history-dialog")).toBeVisible();
- fireEvent.click(queryByTestId("status-bar-dialog-close"));
+ fireEvent.click(queryByTestId("history-dialog-close"));
await waitFor(() => expect(queryByTestId("status-bar-history-dialog")).toBeNull());
});
diff --git a/src/components/StatusBar/components/HistorySection.tsx b/src/components/StatusBar/components/HistorySection.tsx
index 1374e69e..242af131 100644
--- a/src/components/StatusBar/components/HistorySection.tsx
+++ b/src/components/StatusBar/components/HistorySection.tsx
@@ -1,19 +1,10 @@
-import { CSSProperties, FC, useMemo, useState } from "react";
-import {
- Avatar,
- Button,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- Stack,
- Typography,
-} from "@mui/material";
-import { Timeline, TimelineItem, TimelineSeparator, TimelineDot, TimelineContent } from "@mui/lab";
+import { CSSProperties, FC, useState } from "react";
+import { Button } from "@mui/material";
import { styled } from "@mui/material/styles";
import { useFormContext } from "../../Contexts/FormContext";
-import { HistoryIconMap } from "../../../assets/history/submissionRequest";
-import { FormatDate, SortHistory } from "../../../utils";
+import { HistoryIconMap } from "./SubmissionRequestIconMap";
+import { FormatDate } from "../../../utils";
+import HistoryDialog from "../../HistoryDialog";
/**
* Determines the text color for a History event based
@@ -64,158 +55,6 @@ const StyledButton = styled(Button)({
},
});
-const StyledDialog = styled(Dialog)({
- "& .MuiDialog-paper": {
- borderRadius: "8px",
- boxShadow: "0px 4px 45px 0px rgba(0, 0, 0, 0.40)",
- padding: "28px 24px",
- width: "567px !important",
- border: "2px solid #388DEE",
- background: "#2E4D7B",
- },
-});
-
-const StyledDialogTitle = styled(DialogTitle)({
- paddingBottom: "0",
-});
-
-const StyledPreTitle = styled("p")({
- color: "#D5DAE7",
- fontSize: "13px",
- fontFamily: "Nunito Sans",
- lineHeight: "27px",
- letterSpacing: "0.5px",
- textTransform: "uppercase",
- margin: "0",
-});
-
-const StyledTitle = styled("p")({
- color: "#FFF",
- fontSize: "35px",
- fontFamily: "Nunito Sans",
- fontWeight: "900",
- lineHeight: "30px",
- margin: "0",
-});
-
-const StyledDialogContent = styled(DialogContent)({
- marginTop: "20px",
- marginBottom: "22px",
-});
-
-const StyledTimelineItem = styled(TimelineItem)({
- alignItems: "center",
- "&::before": {
- flex: "0",
- padding: "0",
- paddingLeft: "55px",
- },
- // Add vertical separator line between timeline items
- "&:not(:last-of-type)::after": {
- content: '" "',
- height: "1px",
- left: "0",
- right: "0",
- bottom: "0",
- position: "absolute",
- background: "#033277",
- },
- // Add vertical lines between timeline item dots (top)
- "&:not(:first-of-type) .MuiTimelineSeparator-root::before": {
- content: '" "',
- width: "6px",
- background: "#fff",
- top: "0",
- bottom: "50%",
- right: "50%",
- position: "absolute",
- transform: "translateX(50%)",
- zIndex: "1",
- },
- // Add vertical lines between timeline item dots (bottom)
- "&:not(:last-of-type) .MuiTimelineSeparator-root::after": {
- content: '" "',
- width: "6px",
- background: "#fff",
- top: "50%",
- bottom: "0",
- right: "50%",
- position: "absolute",
- transform: "translateX(50%)",
- zIndex: "1",
- },
-});
-
-const StyledTimelineSeparator = styled(TimelineSeparator)({
- position: "relative",
- minHeight: "70px",
-});
-
-const StyledTimelineDot = styled(TimelineDot)({
- background: "#fff",
- borderWidth: "4px",
- margin: "0",
- zIndex: "2",
- position: "absolute",
- top: "50%",
- left: "50%",
- transform: "translate(-50%, -50%)",
-});
-
-const StyledTimelineVerticalLine = styled("span")({
- width: "60px",
- height: "2px",
- background: "#fff",
- position: "absolute",
- top: "50%",
- left: "50%",
- "&::after": {
- content: '" "',
- width: "6px",
- height: "6px",
- borderRadius: "50%",
- background: "#fff",
- top: "50%",
- bottom: "0",
- right: "0",
- position: "absolute",
- transform: "translateY(-50%)",
- zIndex: "1",
- },
-});
-
-const StyledTimelineContent = styled(TimelineContent)({
- marginLeft: "60px",
- color: "#fff",
-});
-
-const StyledTypography = styled(Typography)<{ status?: ApplicationStatus }>(({ status }) => ({
- lineHeight: "2.5",
- minWidth: "100px",
- textAlign: "left",
- color: getStatusColor(status),
-}));
-
-const StyledAvatar = styled(Avatar)({
- background: "transparent",
- marginRight: "8px",
-});
-
-const StyledCloseButton = styled(Button)({
- minWidth: "137px",
- fontWeight: "700",
- borderRadius: "8px",
- textTransform: "none",
- color: "#fff",
- borderColor: "#fff",
- margin: "0 auto",
- padding: "10px",
- lineHeight: "24px",
- "&:hover": {
- borderColor: "#fff",
- },
-});
-
/**
* Status Bar History Section
*
@@ -226,7 +65,6 @@ const HistorySection: FC = () => {
data: { updatedAt, history },
} = useFormContext();
const [open, setOpen] = useState(false);
- const sortedHistory = useMemo(() => SortHistory(history), [history]);
return (
<>
@@ -246,61 +84,16 @@ const HistorySection: FC = () => {
>
Full History
- setOpen(false)}
- scroll="body"
data-testid="status-bar-history-dialog"
- >
-
- CRDC Submission Request
- Submission History
-
-
-
- {sortedHistory.map(({ status, dateTime }, index) => (
-
-
-
-
-
-
-
-
- {FormatDate(dateTime, "M/D/YYYY", "N/A")}
-
- {status?.toUpperCase()}
- {index === 0 && HistoryIconMap[status] && (
-
-
-
- )}
-
-
-
- ))}
-
-
-
- setOpen(false)}
- variant="outlined"
- size="large"
- aria-label="Close dialog"
- data-testid="status-bar-dialog-close"
- >
- Close
-
-
-
+ />
>
)}
>
diff --git a/src/components/StatusBar/components/StatusSection.tsx b/src/components/StatusBar/components/StatusSection.tsx
index 75c9dc17..0f2f91d1 100644
--- a/src/components/StatusBar/components/StatusSection.tsx
+++ b/src/components/StatusBar/components/StatusSection.tsx
@@ -2,7 +2,7 @@ import { CSSProperties, FC, useMemo, useState } from "react";
import { Avatar, Button } from "@mui/material";
import { styled } from "@mui/material/styles";
import { useFormContext } from "../../Contexts/FormContext";
-import { StatusIconMap } from "../../../assets/history/submissionRequest";
+import { StatusIconMap } from "./SubmissionRequestIconMap";
import { SortHistory } from "../../../utils";
import ReviewCommentsDialog from "../../Shared/ReviewCommentsDialog";
diff --git a/src/components/StatusBar/components/SubmissionRequestIconMap.tsx b/src/components/StatusBar/components/SubmissionRequestIconMap.tsx
new file mode 100644
index 00000000..705f8cff
--- /dev/null
+++ b/src/components/StatusBar/components/SubmissionRequestIconMap.tsx
@@ -0,0 +1,33 @@
+import New from "../../../assets/history/submissionRequest/SubmissionRequestNew.svg";
+import Submitted from "../../../assets/history/submissionRequest/SubmissionRequestSubmitted.svg";
+import Rejected from "../../../assets/history/submissionRequest/Rejected.svg";
+import Approved from "../../../assets/history/submissionRequest/Approved.svg";
+import UnderReview from "../../../assets/history/submissionRequest/UnderReview.svg";
+import StatusApproved from "../../../assets/history/submissionRequest/StatusApproved.svg";
+import StatusRejected from "../../../assets/history/submissionRequest/StatusRejected.svg";
+import InProgress from "../../../assets/history/submissionRequest/InProgress.svg";
+import { IconType } from "../../HistoryDialog";
+
+/**
+ * Map of ApplicationStatus to Icon for History Modal
+ *
+ * @see ApplicationStatus
+ */
+export const HistoryIconMap: IconType = {
+ New,
+ Submitted,
+ Rejected,
+ Approved,
+ "In Review": UnderReview,
+ "In Progress": InProgress,
+} as IconType;
+
+/**
+ * Map of ApplicationStatus to Icon for Status Bar
+ *
+ * @see ApplicationStatus
+ */
+export const StatusIconMap: IconType = {
+ Rejected: StatusRejected,
+ Approved: StatusApproved,
+} as IconType;
diff --git a/src/content/dataSubmissions/DataSubmission.tsx b/src/content/dataSubmissions/DataSubmission.tsx
index 818c7a7c..b4c54652 100644
--- a/src/content/dataSubmissions/DataSubmission.tsx
+++ b/src/content/dataSubmissions/DataSubmission.tsx
@@ -1,28 +1,15 @@
import { FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useMutation } from "@apollo/client";
-import {
- Alert,
- Box,
- Card,
- CardActions,
- CardContent,
- Container,
- IconButton,
- Stack,
- Tabs,
- Typography,
- styled,
-} from "@mui/material";
+import { Alert, Box, Card, CardActions, CardContent, Container, Tabs, styled } from "@mui/material";
import { useSnackbar, VariantType } from "notistack";
-import bannerPng from "../../assets/dataSubmissions/dashboard_banner.png";
-import summaryBannerSvg from "../../assets/dataSubmissions/summary_banner.png";
+import bannerPng from "../../assets/banner/submission_banner.png";
+import summaryBannerPng from "../../assets/banner/summary_banner.png";
import LinkTab from "../../components/DataSubmissions/LinkTab";
import MetadataUpload from "../../components/DataSubmissions/MetadataUpload";
import { SUBMISSION_ACTION, SubmissionActionResp } from "../../graphql";
import DataSubmissionSummary from "../../components/DataSubmissions/DataSubmissionSummary";
import DataSubmissionActions from "./DataSubmissionActions";
import QualityControl from "./QualityControl";
-import { ReactComponent as CopyIconSvg } from "../../assets/icons/copy_icon_2.svg";
import ValidationStatistics from "../../components/DataSubmissions/ValidationStatistics";
import ValidationControls from "../../components/DataSubmissions/ValidationControls";
import { useAuthContext } from "../../components/Contexts/AuthContext";
@@ -41,19 +28,15 @@ import { useSubmissionContext } from "../../components/Contexts/SubmissionContex
import DataActivity, { DataActivityRef } from "./DataActivity";
import CrossValidation from "./CrossValidation";
import { CrossValidateRoles } from "../../config/AuthRoles";
+import CopyAdornment from "../../components/DataSubmissions/CopyAdornment";
const StyledBanner = styled("div")(({ bannerSrc }: { bannerSrc: string }) => ({
background: `url(${bannerSrc})`,
backgroundBlendMode: "luminosity, normal",
backgroundSize: "cover",
- backgroundRepeat: "no-repeat",
- backgroundPosition: "top",
+ backgroundPosition: "center",
width: "100%",
- height: "295px",
- display: "flex",
- justifyContent: "center",
- alignItems: "center",
- position: "relative",
+ height: "296px",
zIndex: 0,
}));
@@ -150,53 +133,12 @@ const StyledWrapper = styled("div")({
});
const StyledCardContent = styled(CardContent)({
- background: `url(${summaryBannerSvg})`,
+ background: `url(${summaryBannerPng})`,
backgroundSize: "auto",
backgroundRepeat: "no-repeat",
backgroundPosition: "top",
});
-const StyledCopyWrapper = styled(Stack)(() => ({
- height: "42px",
- width: "fit-content",
- minWidth: "342px",
- padding: "11px 20px",
- borderRadius: "8px 8px 0px 0px",
- borderTop: "1.25px solid #6DADDB",
- borderRight: "1.25px solid #6DADDB",
- borderLeft: "1.25px solid #6DADDB",
- background: "#EAF5F8",
-}));
-
-const StyledCopyLabel = styled(Typography)(() => ({
- color: "#125868",
- fontFamily: "'Nunito', 'Rubik', sans-serif",
- fontSize: "12px",
- fontStyle: "normal",
- fontWeight: 800,
- lineHeight: "19.6px",
- letterSpacing: "0.24px",
- textTransform: "uppercase",
-}));
-
-const StyledCopyValue = styled(Typography)(() => ({
- color: "#125868",
- fontFamily: "'Nunito', 'Rubik', sans-serif",
- fontSize: "16px",
- fontStyle: "normal",
- fontWeight: 400,
- lineHeight: "19.6px",
- letterSpacing: "0.32px",
-}));
-
-const StyledCopyIDButton = styled(IconButton)(() => ({
- color: "#000000",
- padding: 0,
- "&.MuiIconButton-root.Mui-disabled": {
- color: "#B0B0B0",
- },
-}));
-
const StyledFlowContainer = styled(Box)({
padding: "27px 59px 59px 60px",
});
@@ -309,13 +251,6 @@ const DataSubmission: FC = ({ submissionId, tab = URLTabs.UPLOAD_ACTIVITY
[enqueueSnackbar, handleBatchRefresh, getSubmission]
);
- const handleCopyID = () => {
- if (!submissionId) {
- return;
- }
- navigator.clipboard.writeText(submissionId);
- };
-
useEffect(() => {
if (!submissionId) {
setError("Invalid submission ID provided.");
@@ -328,23 +263,7 @@ const DataSubmission: FC = ({ submissionId, tab = URLTabs.UPLOAD_ACTIVITY
-
-
- SUBMISSION ID:
-
-
- {submissionId}
-
- {submissionId && (
-
-
-
- )}
-
+
{error && Oops! An error occurred. {error}}
diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx
index 1c127e73..d94fa4ba 100644
--- a/src/layouts/index.tsx
+++ b/src/layouts/index.tsx
@@ -26,7 +26,7 @@ const Layout: FC = ({ children }) => (
href={
"https://fonts.googleapis.com/css2?" +
"family=Open+Sans&" +
- "family=Poppins:wght@400;700&" +
+ "family=Poppins:wght@400;600;700&" +
"family=Lato:wght@300;400;500;600;700&" +
"family=Inter:wght@300;400;500;600;700&" +
"family=Nunito+Sans:wght@400;500;600;700;800;900&" +