Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
318 changes: 206 additions & 112 deletions src/components/EmailDeliveryReport/EmailDeliveryReport.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Tag, Button, Row, Col } from "antd";
import { useState, Key } from "react";
import { Tag, Button, Row, Col, message } from "antd";
import { useState, Key, useEffect } from "react";
import { StyledTable, StyledTag } from "./EmailDeliveryReport.styled";

import { ColumnType } from "antd/es/table";
import { ClearOutlined, ReloadOutlined } from "@ant-design/icons";
import { getEmailDeliveryReportEnumerator } from "../../redux/emails/apiService";

interface EnumeratorStatus {
enumerator_id: string;
Expand All @@ -14,93 +16,200 @@ interface EnumeratorStatus {
supervisor_email: string;
}

const columns: ColumnType<EnumeratorStatus>[] = [
{
title: "Enumerator ID",
dataIndex: "enumerator_id",
key: "enumerator_id",
sorter: (a, b) => a.enumerator_id.localeCompare(b.enumerator_id),
},
{
title: "Enumerator Name",
dataIndex: "enumerator_name",
key: "enumerator_name",
sorter: (a, b) => a.enumerator_name.localeCompare(b.enumerator_name),
},
{
title: "Enumerator Email",
dataIndex: "enumerator_email",
key: "enumerator_email",
sorter: (a, b) => a.enumerator_email.localeCompare(b.enumerator_email),
},
{
title: "Status",
dataIndex: "status",
key: "status",
filters: [
{ text: "Sent", value: "sent" },
{ text: "Failed", value: "failed" },
],
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
typeof value === "boolean"
? false
: record.status.includes(value.toString()),
sorter: (a, b) => a.status.localeCompare(b.status),
render: (status: string) => {
let color = "green";
if (status === "failed") {
color = "red";
}
return (
<Tag color={color} key={status}>
{status.toUpperCase()}
</Tag>
);
},
},
{
title: "Error",
dataIndex: "error_message",
key: "error_message",
sorter: (a, b) => a.error_message.localeCompare(b.error_message),
},
{
title: "Supervisor Name",
dataIndex: "supervisor_name",
key: "supervisor_name",
sorter: (a, b) => a.supervisor_name.localeCompare(b.supervisor_name),
},
{
title: "Supervisor Email",
dataIndex: "supervisor_email",
key: "supervisor_email",
sorter: (a, b) => a.supervisor_email.localeCompare(b.supervisor_email),
},
];

const formatDateTime = (date: string) => {
return new Date(date).toLocaleString();
};

const combineSlotDateTime = (slot_date: string, slot_time: string) => {
const cleanedSlotDate = new Date(slot_date).toDateString();
const combinedDateTime = new Date(
`${cleanedSlotDate} ${slot_time}`
).toLocaleString();
return combinedDateTime;
};

function EmailDeliveryReport({
deliveryReportData,
slot_type,
email_config_uid,
}: {
deliveryReportData: any;
slot_type: string;
email_config_uid?: string;
}) {
const [selectedReportUID, setSelectedReportUID] = useState<null | string>(
deliveryReportData[0].email_delivery_report_uid
);
const [tableKey, setTableKey] = useState<number>(0);
const [enumeratorData, setEnumeratorData] = useState<EnumeratorStatus[]>([]);
const [loading, setLoading] = useState<boolean>(false);

const selectedReport = deliveryReportData.find(
(report: any) => report.email_delivery_report_uid === selectedReportUID
);

// Function to fetch enumerator data for selected report
const fetchEnumeratorData = async (reportUID: string) => {
if (!reportUID) return;

const configUID = email_config_uid || selectedReport?.email_config_uid;
if (!configUID) return;

setLoading(true);
try {
const response = await getEmailDeliveryReportEnumerator(
configUID,
reportUID
);

if ((response as any)?.data?.success) {
const responseData = (response as any).data.data;
// Find the matching delivery report and extract enumerator_status
const matchingReport = responseData.find(
(report: any) =>
report.email_delivery_report_uid.toString() === reportUID
);
setEnumeratorData(matchingReport?.enumerator_status || []);
} else {
setEnumeratorData([]);
message.error("Failed to fetch enumerator data");
}
} catch (error) {
console.error("Error fetching enumerator data:", error);
setEnumeratorData([]);
message.error("Error occurred while fetching enumerator data");
} finally {
setLoading(false);
}
};

// Effect to fetch enumerator data when selectedReportUID changes
useEffect(() => {
if (selectedReportUID) {
fetchEnumeratorData(selectedReportUID);
}
}, [selectedReportUID, selectedReport]);

const columns: ColumnType<EnumeratorStatus>[] = [
{
title: "Enumerator ID",
dataIndex: "enumerator_id",
key: "enumerator_id",
sorter: (a, b) => a.enumerator_id.localeCompare(b.enumerator_id),
filters: Array.from(
new Set(
enumeratorData.map(
(status: EnumeratorStatus) => status.enumerator_id
) || []
)
).map((id) => ({ text: String(id), value: String(id) })),
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
record.enumerator_id === value,
},
{
title: "Enumerator Name",
dataIndex: "enumerator_name",
key: "enumerator_name",
sorter: (a, b) => a.enumerator_name.localeCompare(b.enumerator_name),
filters: Array.from(
new Set(
enumeratorData.map(
(status: EnumeratorStatus) => status.enumerator_name
) || []
)
).map((name) => ({ text: String(name), value: String(name) })),
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
record.enumerator_name === value,
},
{
title: "Enumerator Email",
dataIndex: "enumerator_email",
key: "enumerator_email",
sorter: (a, b) => a.enumerator_email.localeCompare(b.enumerator_email),
filters: Array.from(
new Set(
enumeratorData.map(
(status: EnumeratorStatus) => status.enumerator_email
) || []
)
).map((email) => ({ text: String(email), value: String(email) })),
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
record.enumerator_email === value,
},
{
title: "Status",
dataIndex: "status",
key: "status",
filters: [
{ text: "Sent", value: "sent" },
{ text: "Failed", value: "failed" },
],
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
typeof value === "boolean"
? false
: record.status.includes(value.toString()),
sorter: (a, b) => a.status.localeCompare(b.status),
render: (status: string) => {
let color = "green";
if (status === "failed") {
color = "red";
}
return (
<Tag color={color} key={status}>
{status.toUpperCase()}
</Tag>
);
},
},
{
title: "Error",
dataIndex: "error_message",
key: "error_message",
filters: Array.from(
new Set(
enumeratorData.map(
(status: EnumeratorStatus) => status.error_message || "No Error"
) || []
)
).map((error) => ({ text: String(error), value: String(error) })),
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
(record.error_message || "No Error") === value,
sorter: (a, b) =>
(a.error_message || "").localeCompare(b.error_message || ""),
},
{
title: "Supervisor Name",
dataIndex: "supervisor_name",
key: "supervisor_name",
sorter: (a, b) => a.supervisor_name.localeCompare(b.supervisor_name),
filters: Array.from(
new Set(
enumeratorData.map(
(status: EnumeratorStatus) => status.supervisor_name
) || []
)
).map((name) => ({ text: String(name), value: String(name) })),
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
record.supervisor_name === value,
},
{
title: "Supervisor Email",
dataIndex: "supervisor_email",
key: "supervisor_email",
sorter: (a, b) => a.supervisor_email.localeCompare(b.supervisor_email),
filters: Array.from(
new Set(
enumeratorData.map(
(status: EnumeratorStatus) => status.supervisor_email
) || []
)
).map((email) => ({ text: String(email), value: String(email) })),
onFilter: (value: boolean | Key, record: EnumeratorStatus) =>
record.supervisor_email === value,
},
];

const formatDateTime = (date: string) => {
return new Date(date).toLocaleString();
};

const combineSlotDateTime = (slot_date: string, slot_time: string) => {
const cleanedSlotDate = new Date(slot_date).toDateString();
const combinedDateTime = new Date(
`${cleanedSlotDate} ${slot_time}`
).toLocaleString();
return combinedDateTime;
};

const tableData = enumeratorData || [];

const resetTable = () => {
setTableKey((prevKey) => prevKey + 1);
Expand Down Expand Up @@ -165,52 +274,37 @@ function EmailDeliveryReport({
<Row style={{ marginTop: "20px", fontSize: "20px" }}>
<Col span={8}>
<StyledTag color="green">
Total Enumerators with emails Sent:{" "}
Emails Sent to Enumerators:{" "}
{
deliveryReportData
.find(
(report: any) =>
report.email_delivery_report_uid == selectedReportUID
)
?.enumerator_status.filter(
(status: EnumeratorStatus) => status.status === "sent"
).length
enumeratorData.filter(
(status: EnumeratorStatus) => status.status === "sent"
).length
}
</StyledTag>
</Col>
<Col span={8}>
<StyledTag color="red">
Total Enumerators with emails Failed:{" "}
Emails Failed for Enumerators:{" "}
{
deliveryReportData
.find(
(report: any) =>
report.email_delivery_report_uid == selectedReportUID
)
?.enumerator_status.filter(
(status: EnumeratorStatus) => status.status === "failed"
).length
enumeratorData.filter(
(status: EnumeratorStatus) => status.status === "failed"
).length
}
</StyledTag>
</Col>
<Col span={4} offset={4}>
<Button onClick={resetTable}>Clear Sort and Filters</Button>
<Col span={1} offset={7}>
<Button onClick={resetTable} icon={<ClearOutlined />} />
</Col>
</Row>
<span style={{ width: "100%" }}>
<StyledTable
key={tableKey}
columns={columns as any}
dataSource={
deliveryReportData.find(
(report: any) =>
report.email_delivery_report_uid == selectedReportUID
)?.enumerator_status
}
rowKey="enumerator_id"
style={{ width: "100%", marginTop: "40px" }}
/>
</span>
<StyledTable
key={tableKey}
bordered={true}
columns={columns as any}
dataSource={tableData}
rowKey="enumerator_id"
style={{ width: "100%", marginTop: "40px" }}
loading={loading}
/>
</>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,9 @@ function CreateAssignments() {
>
Email configuration: <b>{email.config_name}</b>,
Date: <b>{email.schedule_time}</b>, Time:{" "}
<b>{email.time}</b>
<b>
{dayjs(email.time, "HH:mm").format("hh:mm A")}
</b>
</li>
)
)}
Expand Down Expand Up @@ -917,6 +919,9 @@ function CreateAssignments() {
size="middle"
format="YYYY-MM-DD"
style={{ width: 250 }}
disabledDate={(current) =>
current && current < dayjs().startOf("day")
}
onChange={handleDateChange}
/>
</Form.Item>
Expand All @@ -933,7 +938,7 @@ function CreateAssignments() {
>
<TimePicker
placeholder="Select Time"
format="HH:mm"
format="hh:mm A"
minuteStep={30}
style={{ width: 250 }}
showNow={false}
Expand Down
Loading