Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 13586c2

Browse files
git push origin developMerge branch 'cagdas001-develop' into develop
2 parents a894f3d + df7abf2 commit 13586c2

File tree

4 files changed

+213
-23
lines changed

4 files changed

+213
-23
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
* Content of the Table component.
3+
*/
4+
5+
import React from "react";
6+
import PT from "prop-types";
7+
import _ from "lodash";
8+
9+
import style from "./style.module.scss";
10+
11+
export const TABLE_STATES = {
12+
LOADING_LAST_UPLOADS: "LOADING_LAST_UPLOADS",
13+
RESULT: "RESULT",
14+
};
15+
16+
export default function Table({ state, data }) {
17+
const columns = {
18+
created: {
19+
name: "Upload Date",
20+
formatter: (date) =>
21+
new Intl.DateTimeFormat("en", {
22+
year: "numeric",
23+
month: "short",
24+
day: "2-digit",
25+
hour: "2-digit",
26+
minute: "2-digit",
27+
}).format(new Date(date)),
28+
},
29+
status: { name: "Status" },
30+
info: { name: "Info" },
31+
failedRecordsUrl: {
32+
name: "Assets",
33+
formatter: (url) =>
34+
url ? (
35+
<a href={url} target="_blank" rel="noopener noreferrer">
36+
Download
37+
</a>
38+
) : (
39+
"-"
40+
),
41+
},
42+
};
43+
44+
return state === TABLE_STATES.LOADING_LAST_UPLOADS ? (
45+
<div className={style.content}>
46+
<h1 className={style.title}>Gathering status of older uploads...</h1>
47+
</div>
48+
) : data.length > 0 ? (
49+
<div className={style.content}>
50+
<h1 className={style.title}>Past 24 Hours Upload Status</h1>
51+
<table className={style.tableContent}>
52+
<thead>
53+
<tr>
54+
{_.map(_.values(columns), ({ name }, i) => (
55+
<th key={i}>{name}</th>
56+
))}
57+
</tr>
58+
</thead>
59+
<tbody>
60+
{_.map(data, (item, i) => (
61+
<tr key={i}>
62+
{_.map(_.keys(columns), (colKey, j) => (
63+
<td key={j}>
64+
{columns[colKey].formatter
65+
? columns[colKey].formatter(item[colKey])
66+
: item[colKey] || "-"}
67+
</td>
68+
))}
69+
</tr>
70+
))}
71+
</tbody>
72+
</table>
73+
</div>
74+
) : (
75+
<div className={style.content}>
76+
<h1 className={style.title}>Past 24 Hours Upload Status</h1>
77+
<table className={style.tableContent}>
78+
<thead>
79+
<tr>
80+
{_.map(_.values(columns), ({ name }, i) => (
81+
<th key={i}>{name}</th>
82+
))}
83+
</tr>
84+
</thead>
85+
<tbody>
86+
<tr>
87+
<td colSpan="4">No records uploaded in the past 24 hours</td>
88+
</tr>
89+
</tbody>
90+
</table>
91+
</div>
92+
);
93+
}
94+
95+
Table.propTypes = {
96+
state: PT.any,
97+
data: PT.array.isRequired,
98+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
.content {
2+
margin-top: 15px;
3+
margin-bottom: 15px;
4+
}
5+
6+
.title {
7+
text-align: center;
8+
color: #252526;
9+
font: 500 14pt Inter;
10+
}
11+
12+
.tableContent {
13+
margin-top: 15px;
14+
margin-bottom: 15px;
15+
margin-left: auto;
16+
margin-right: auto;
17+
width: 70%;
18+
}
19+
20+
table {
21+
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
22+
border-collapse: collapse;
23+
}
24+
25+
th {
26+
padding-top: 12px;
27+
padding-bottom: 12px;
28+
text-align: center;
29+
background-color: #3cd656;
30+
color: white;
31+
}
32+
33+
td {
34+
border: 1px solid #ddd;
35+
padding: 8px;
36+
text-align: center;
37+
}
38+
39+
tr:nth-child(even) {
40+
background-color: #f2f2f2;
41+
}
42+
tr:hover {
43+
background-color: #ddd;
44+
}
45+
46+
a {
47+
color: #30a2c7;
48+
text-decoration: none;
49+
&:hover {
50+
color: #56ccf2;
51+
text-decoration: underline;
52+
}
53+
}

client/src/components/Upload/index.jsx

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ import FormData from "form-data";
44
import PT from "prop-types";
55

66
import Container from "./Container";
7+
import Table, { TABLE_STATES } from "./Table";
78
import Initial from "./Initial";
89
import Message from "./Message";
910
import Progress from "./Progress";
1011

12+
import style from "./style.module.scss";
13+
1114
import config from "../../config";
1215
import api from "../../services/api";
1316
import { getSingleOrg } from "../../services/user-org";
1417

15-
const STATES = {
18+
const UPLOAD_STATES = {
1619
INITIAL: "INITIAL",
1720
MESSAGE: "MESSAGE",
1821
RESULT: "RESULT",
@@ -21,15 +24,19 @@ const STATES = {
2124

2225
export default function Upload({ templateId }) {
2326
const apiClient = api();
24-
const [state, setState] = React.useState({
25-
type: STATES.INITIAL,
27+
const [uploadState, setUploadState] = React.useState({
28+
type: UPLOAD_STATES.INITIAL,
2629
data: null,
2730
});
31+
const [tableState, setTableState] = React.useState(
32+
TABLE_STATES.LOADING_LAST_UPLOADS
33+
);
34+
const [lastUploads, setLastUploads] = React.useState([]);
2835

2936
const showError = (error) => {
3037
const { message } = error.toJSON ? error.toJSON() : error;
31-
setState({
32-
type: STATES.MESSAGE,
38+
setUploadState({
39+
type: UPLOAD_STATES.MESSAGE,
3340
data: {
3441
title: "Error Occured",
3542
message,
@@ -44,8 +51,8 @@ export default function Upload({ templateId }) {
4451
data.append("upload", file);
4552
data.append("organizationId", getSingleOrg());
4653

47-
setState({
48-
type: STATES.UPLOADING,
54+
setUploadState({
55+
type: UPLOAD_STATES.UPLOADING,
4956
data: { progress: 0 },
5057
});
5158

@@ -55,17 +62,17 @@ export default function Upload({ templateId }) {
5562
"Content-Type": "multipart/form-data",
5663
},
5764
onUploadProgress: ({ loaded, total }) => {
58-
setState({
59-
type: STATES.UPLOADING,
65+
setUploadState({
66+
type: UPLOAD_STATES.UPLOADING,
6067
data: {
6168
progress: loaded / total,
6269
},
6370
});
6471
},
6572
});
6673

67-
setState({
68-
type: STATES.MESSAGE,
74+
setUploadState({
75+
type: UPLOAD_STATES.MESSAGE,
6976
data: {
7077
title: "Profiles uploaded successfully",
7178
message:
@@ -77,33 +84,57 @@ export default function Upload({ templateId }) {
7784
}
7885
};
7986

80-
let content;
81-
switch (state.type) {
82-
case STATES.MESSAGE:
83-
content = (
87+
React.useEffect(() => {
88+
async function fetchUploads() {
89+
const url = `${config.API_PREFIX}/uploads`;
90+
91+
setTableState(TABLE_STATES.LOADING_LAST_UPLOADS);
92+
93+
try {
94+
const { data } = await apiClient.get(url);
95+
96+
setTableState(TABLE_STATES.RESULT);
97+
setLastUploads(data);
98+
} catch (error) {
99+
setTableState(TABLE_STATES.RESULT);
100+
setLastUploads([]);
101+
}
102+
}
103+
fetchUploads();
104+
}, [apiClient]);
105+
106+
let uploadSectionContent;
107+
switch (uploadState.type) {
108+
case UPLOAD_STATES.MESSAGE:
109+
uploadSectionContent = (
84110
<Message
85-
message={state.data.message}
86-
onClose={() => setState({ type: STATES.INITIAL })}
87-
title={state.data.title}
111+
message={uploadState.data.message}
112+
onClose={() => setUploadState({ type: UPLOAD_STATES.INITIAL })}
113+
title={uploadState.data.title}
88114
/>
89115
);
90116
break;
91-
case STATES.INITIAL:
92-
content = (
117+
case UPLOAD_STATES.INITIAL:
118+
uploadSectionContent = (
93119
<Initial
94120
onError={showError}
95121
onUpload={upload}
96122
templateId={templateId}
97123
/>
98124
);
99125
break;
100-
case STATES.UPLOADING:
101-
content = <Progress progress={state.data.progress} />;
126+
case UPLOAD_STATES.UPLOADING:
127+
uploadSectionContent = <Progress progress={uploadState.data.progress} />;
102128
break;
103129
default:
104130
throw Error("Invalid state");
105131
}
106-
return <Container>{content}</Container>;
132+
return (
133+
<div className={style.content}>
134+
<Table state={tableState} data={lastUploads} />
135+
<Container>{uploadSectionContent}</Container>
136+
</div>
137+
);
107138
}
108139

109140
Upload.propTypes = {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.content {
2+
background: #eee;
3+
border-radius: 10px;
4+
margin: auto;
5+
position: relative;
6+
user-select: none;
7+
width: 80%;
8+
}

0 commit comments

Comments
 (0)