Skip to content

Commit

Permalink
Merge pull request #42 from cph-cachet/jakdan99/download-informed-con…
Browse files Browse the repository at this point in the history
…sent-pdf

Download informed consent pdf
  • Loading branch information
jakdan99 authored Nov 27, 2024
2 parents 6c4096e + 9a61e3b commit 842550c
Show file tree
Hide file tree
Showing 9 changed files with 588 additions and 73 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@mui/system": "^5.15.20",
"@mui/x-charts": "^7.7.0",
"@mui/x-date-pickers": "^7.6.2",
"@react-pdf/renderer": "^4.1.4",
"@tanstack/react-query": "^5.45.0",
"@tanstack/react-query-devtools": "^5.45.0",
"big.js": "^6.2.1",
Expand Down
375 changes: 375 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/pages/Deployment/Devices/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,25 +99,25 @@ const Devices = () => {
.map((connection) => {
const deviceStatus = participantGroupsAndStatuses.groups
.find((s) => s.participantGroupId === deploymentId)
.deploymentStatus.deviceStatusList.find(
?.deploymentStatus.deviceStatusList.find(
(d) => d.device.roleName === connection.roleName,
);
return {
name: connection.roleName,
type: deviceStatus.device.__type,
status: deviceStatus.__type.split(".").pop(),
type: deviceStatus?.device.__type,
status: deviceStatus?.__type.split(".").pop(),
};
});
const deviceStatus = participantGroupsAndStatuses.groups
.find((s) => s.participantGroupId === deploymentId)
.deploymentStatus.deviceStatusList.find(
?.deploymentStatus.deviceStatusList.find(
(d) => d.device.roleName === device.roleName,
);
return {
primaryDevice: {
name: device.roleName,
type: deviceStatus.device.__type,
status: deviceStatus.__type.split(".").pop(),
type: deviceStatus?.device.__type,
status: deviceStatus?.__type.split(".").pop(),
},
connections,
};
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Deployment/Devices/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const ModalBox = styled("div")(({ theme }) => ({
}));

export const Title = styled(Typography)(({ theme }) => ({
color: theme.palette.error.main,
color: theme.palette.primary.main,
marginBottom: 24,
}));

Expand Down
44 changes: 13 additions & 31 deletions src/pages/Deployment/InformedConsentCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
import { useEffect, useState } from "react";
import { InformedConsent } from "@carp-dk/client/models/InputDataTypes";
import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
import { formatDateTime } from "@Utils/utility";
import { convertICToReactPdf, formatDateTime } from "@Utils/utility";
import { pdf } from "@react-pdf/renderer";
import {
DownloadButton,
LastUploadText,
Expand All @@ -24,12 +25,6 @@ import {
} from "./styles";
import LoadingSkeleton from "../LoadingSkeleton";

interface FileInfo {
data: string;
fileName: string;
fileType: string;
}

const InformedConsentCard = () => {
const { t } = useTranslation();
const { id: studyId, deploymentId } = useParams();
Expand All @@ -48,10 +43,12 @@ const InformedConsentCard = () => {
const [consents, setConsents] =
useState<{ participant: ParticipantData; consent: InformedConsent }[]>();

const downloadFile = ({ data, fileName, fileType }: FileInfo) => {
const blob = new Blob([data], { type: fileType });
const downloadPdf = async (consent: InformedConsent) => {
const blob = await pdf(
await convertICToReactPdf(JSON.parse(consent.consent)),
).toBlob();
const a = document.createElement("a");
a.download = fileName;
a.download = "informedConsent.pdf";
a.href = window.URL.createObjectURL(blob);
const clickEvt = new MouseEvent("click", {
view: window,
Expand All @@ -62,25 +59,11 @@ const InformedConsentCard = () => {
a.remove();
};

const exportToJson = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
participantId: string,
consent: InformedConsent,
) => {
e.preventDefault();
downloadFile({
data: JSON.stringify(consent),
fileName: `${participantId}_informedConsent.json`,
fileType: "text/json",
});
};

useEffect(() => {
if (statuses && participantData) {
const participantGroup = statuses.groups.find(
(s) => s.participantGroupId === deploymentId,
);

const commonConsent = participantData.common.values
?.toArray()
.find((v) => {
Expand All @@ -90,16 +73,19 @@ const InformedConsentCard = () => {
const roleConsents = (participantData.roles as any as Array<any>).map(
(v) => {
const c =
Object.entries[
v.data[
Object.keys(v.data).find((key) => {
return key.includes("informed_consent");
})
];
return { v, c };
},
);

const participantsWithConsent = participantGroup.participants.map((p) => {
const consent = roleConsents.find((rc) => rc.v.roleName === p.role);
const consent = roleConsents.find((rc) =>
p.role.localeCompare(rc.v.roleName),
);
if (consent) return { participant: p, consent: consent.c };
if (commonConsent) return { participant: p, consent: commonConsent };
return { participant: p, consent: null };
Expand Down Expand Up @@ -155,11 +141,7 @@ const InformedConsentCard = () => {
})}
</LastUploadText>
</i>
<DownloadButton
onClick={(e) =>
exportToJson(e, participant.participantId, consent)
}
>
<DownloadButton onClick={() => downloadPdf(consent)}>
<FileDownloadOutlinedIcon />
<Typography variant="h6">
{t("common:export_data")}
Expand Down
4 changes: 3 additions & 1 deletion src/pages/Deployment/InformedConsentCard/styles.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
Button,
Divider,
Typography,
Accordion,
AccordionSummary,
Stack,
Button,
} from "@mui/material";
import { styled } from "@Utils/theme";

Expand Down Expand Up @@ -67,6 +67,8 @@ export const NameContainer = styled("div")({
});

export const DownloadButton = styled(Button)(({ theme }) => ({
display: "flex",
alignItems: "center",
height: "36px",
color: theme.palette.primary.main,
backgroundColor: "transparent",
Expand Down
51 changes: 18 additions & 33 deletions src/pages/Participant/InformedConsent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-underscore-dangle */
import CarpErrorCardComponent from "@Components/CarpErrorCardComponent";
import { formatDateTime } from "@Utils/utility";
import { convertICToReactPdf, formatDateTime } from "@Utils/utility";
import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
import { Typography } from "@mui/material";
import { useEffect, useMemo, useState } from "react";
Expand All @@ -9,6 +9,7 @@ import {
useGetParticipantData,
useParticipantGroupsAccountsAndStatus,
} from "@Utils/queries/participants";
import { pdf } from "@react-pdf/renderer";
import LoadingSkeleton from "../LoadingSkeleton";
import {
DownloadButton,
Expand All @@ -19,12 +20,6 @@ import {
Title,
} from "./styles";

interface FileInfo {
data: string;
fileName: string;
fileType: string;
}

const InformedConsent = () => {
const { participantId, deploymentId, id: studyId } = useParams();

Expand All @@ -40,10 +35,12 @@ const InformedConsent = () => {
error: participantGroupStatusError,
} = useParticipantGroupsAccountsAndStatus(studyId);

const downloadFile = ({ data, fileName, fileType }: FileInfo) => {
const blob = new Blob([data], { type: fileType });
const downloadPdf = async () => {
const blob = await pdf(
await convertICToReactPdf(JSON.parse(consent.consent)),
).toBlob();
const a = document.createElement("a");
a.download = fileName;
a.download = "informedConsent.pdf";
a.href = window.URL.createObjectURL(blob);
const clickEvt = new MouseEvent("click", {
view: window,
Expand All @@ -54,15 +51,6 @@ const InformedConsent = () => {
a.remove();
};

const exportToJson = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
downloadFile({
data: JSON.stringify(consent),
fileName: "informedConsent.json",
fileType: "text/json",
});
};

useEffect(() => {
if (!isLoading && !participantGroupStatusLoading) {
const participant = participantGroupStatus.groups
Expand All @@ -80,23 +68,20 @@ const InformedConsent = () => {
setConsent(consentData);
}

if (
(participantData.roles as any as Array<any>).find(
(v) =>
v.roleName === participant.assignedParticipantRoles.roleNames[0],
)
) {
const roleConsent = (participantData.roles as any as Array<any>).find(
(v) => {
return Object.values(v.data).find((value) =>
(value as unknown as any)?.__type.includes("informed_consent"),
);
},
const participantRoleData = (
participantData.roles as any as Array<any>
).find(
(v) => v.roleName === participant.assignedParticipantRoles.roleNames[0],
);
if (participantRoleData) {
const roleConsent = Object.values(participantRoleData.data).find(
(value) =>
(value as unknown as any)?.__type.includes("informed_consent"),
);
setConsent(roleConsent);
}
}
}, [participantData]);
}, [participantGroupStatus, participantData]);

const dateOfLastUpdate = useMemo(() => {
if (consent) {
Expand Down Expand Up @@ -128,7 +113,7 @@ const InformedConsent = () => {
{consent && (
<>
<StyledDivider />
<DownloadButton onClick={(e) => exportToJson(e)}>
<DownloadButton onClick={() => downloadPdf()}>
<Typography variant="h6">Export</Typography>
<FileDownloadOutlinedIcon fontSize="small" />
</DownloadButton>
Expand Down
4 changes: 3 additions & 1 deletion src/pages/Participant/InformedConsent/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ export const StyledDivider = styled(Divider)(({ theme }) => ({
borderColor: theme.palette.grey[500],
borderWidth: 1,
width: 1,
marginRight: 8,
marginRight: 16,
marginLeft: 16,
height: 20,
}));

export const DownloadButton = styled(Button)(({ theme }) => ({
display: "flex",
alignItems: "center",
color: theme.palette.primary.main,
backgroundColor: "transparent",
border: "none",
Expand Down
Loading

0 comments on commit 842550c

Please sign in to comment.