Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload old spreadsheets #74

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
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
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-redux": "^8.0.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
Expand Down
21 changes: 18 additions & 3 deletions client/src/Database/DatabasePage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import React, { useState } from 'react';
import { Button } from '@mui/material';
import DataGrid from '../components/DataGrid';
import UploadModal from './UploadModal';

const styles = {
main: {
Expand All @@ -14,17 +15,31 @@ const styles = {
};

export default function DatabasePage() {
const [isModalOpen, setIsModalOpen] = useState(false);

const handleButtonClick = () => {
setIsModalOpen(true);
};

const handleModalClose = () => {
setIsModalOpen(false);
};

return (
<div style={styles.main}>
<DataGrid />
<Button
variant="contained"
color="primary"
style={styles.button}
href="/form"
onClick={handleButtonClick}
>
Add a Referral
Import CSV to Database
</Button>
<UploadModal
isModalOpen={isModalOpen}
handleModalClose={handleModalClose}
/>
</div>
);
}
43 changes: 43 additions & 0 deletions client/src/Database/DropZone.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* eslint-disable react/jsx-props-no-spreading */
import React, { useState, useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
import { Paper, Typography } from '@mui/material';
import COLORS from '../assets/colors';

interface DropZoneProps {
onDrop: (acceptedFiles: File[]) => void;
}
function DropZone({ onDrop }: DropZoneProps) {
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
return (
<Paper
{...getRootProps()}
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
border: '2px dashed',
borderColor: 'primary.main',
borderRadius: 1,
backgroundColor: 'background.paper',
color: 'text.secondary',
p: 2,
width: '100%',
'&:hover': {
backgroundColor: COLORS.lightGray,
},
}}
>
<input {...getInputProps()} />
{isDragActive ? (
<Typography variant="h6">Drop the files here ...</Typography>
) : (
<Typography variant="h6">
Drag and drop files here, or click to select files
</Typography>
)}
</Paper>
);
}
export default DropZone;
82 changes: 82 additions & 0 deletions client/src/Database/UploadModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useState, useCallback } from 'react';
import { Modal, Box, List, Button } from '@mui/material';
import DropZone from './DropZone';
import UploadedFile from './UploadedFile';
import upload from './api';

interface UploadModalProps {
isModalOpen: boolean;
handleModalClose: () => void;
}

const modalStyle = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
backgroundColor: 'white',
padding: '1rem',
width: '400px',
maxHeight: '80vh',
overflowY: 'auto',
textAlign: 'center',
};

function UploadModal({ isModalOpen, handleModalClose }: UploadModalProps) {
const [files, setFiles] = useState<File[]>([]);

const handleSubmit = async () => {
const res = files.map((file) => {
return upload(file);
});
const results = await Promise.all(res);
console.log(results);
const newFiles = files.filter((file, index) => {
return results[index] !== 'Created';
});
setFiles(newFiles);
};

const onDrop = useCallback(
(acceptedFiles: File[]) => {
setFiles([...files, ...acceptedFiles]);
},
[files],
);

const removeFile = (file: File) => {
console.log(file);
const newFiles = [...files];
newFiles.splice(newFiles.indexOf(file), 1);
console.log(newFiles);
setFiles(newFiles);
};

return (
<Modal
open={isModalOpen}
onClose={handleModalClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={modalStyle}>
<DropZone onDrop={onDrop} />
<List>
{files.map((file) => (
<UploadedFile key={file.name} file={file} removeFile={removeFile} />
))}
</List>
<Button
onClick={handleSubmit}
variant="contained"
color="primary"
sx={{ marginTop: '1rem', marginBottom: '1rem' }}
>
Upload File
</Button>
</Box>
</Modal>
);
}

export default UploadModal;
74 changes: 74 additions & 0 deletions client/src/Database/UploadedFile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useEffect, useState } from 'react';
import {
Box,
ListItem,
IconButton,
ListItemText,
LinearProgress,
} from '@mui/material';
import CloseIcon from '@mui/icons-material/Close';

interface UploadedFileProps {
file: File;
removeFile: (file: File) => void;
}
function UploadedFile({ file, removeFile }: UploadedFileProps) {
const [progress, setProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setProgress((oldProgress) => {
const diff = Math.random() * 10;
return Math.min(oldProgress + diff, 100);
});
}, 300);
return () => {
clearInterval(timer);
};
}, []);
return (
<ListItem
alignItems="flex-start"
secondaryAction={
progress === 100 && (
<IconButton
edge="end"
aria-label="delete"
onClick={() => {
console.log(file);
removeFile(file);
}}
>
<CloseIcon />
</IconButton>
)
}
sx={{
py: '7px',
pl: '15px',
pr: '10px',
maxWidth: '100%',
borderRadius: 1,
backgroundColor: 'primary.main',
}}
>
<Box
sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}
>
<ListItemText
primaryTypographyProps={{ color: 'white' }}
primary={file.name}
/>
{progress !== 100 && (
<Box sx={{ width: '100%' }}>
<LinearProgress
variant="determinate"
value={progress}
color="inherit"
/>
</Box>
)}
</Box>
</ListItem>
);
}
export default UploadedFile;
13 changes: 13 additions & 0 deletions client/src/Database/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { postData } from '../util/api';

async function upload(input: File) {
const formData = new FormData();
formData.append('file', input);
const res = await postData('referral/upload', formData);
if (res.error) {
throw Error(res.error.message);
}
return res.data;
}

export default upload;
Loading