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

Issue #10: Improved output formatting #11

Merged
merged 9 commits into from
Oct 20, 2020
119 changes: 96 additions & 23 deletions guids-generator.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script>
<script src="https://unpkg.com/@material-ui/core/umd/material-ui.production.min.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://unpkg.com/react-copy-to-clipboard/build/react-copy-to-clipboard.js"></script>
<script src="https://requirejs.org/docs/release/2.1.5/comments/require.js"></script>
</head>
<body>
Expand All @@ -30,7 +31,8 @@
require(["bcrypt"], function(bcrypt) {

const { useState } = window['React'];
const { TextField, InputAdornment, Icon, Button, IconButton, Typography, makeStyles, Grid, List, ListItem, ListItemText, FormControl, Select, MenuItem, FormHelperText, InputLabel } = window['MaterialUI'];
const { TextField, InputAdornment, Icon, Button, IconButton, Typography, makeStyles, withStyles, Grid, FormControl, Select, MenuItem, FormHelperText, InputLabel, Table, TableHead, TableRow, TableCell, TableBody, TableContainer, Paper } = window['MaterialUI'];
const { CopyToClipboard } = window['CopyToClipboard'];

const useStyles = makeStyles((theme) => ({
bform: {
Expand All @@ -53,10 +55,6 @@
formControl: {
width: theme.spacing(50),
},
boutput: {
width: theme.spacing(70),
marginBottom: theme.spacing(0),
},
labelRoot: {
width: theme.spacing(70),
color: theme.palette.text.primary,
Expand All @@ -74,11 +72,46 @@
helperText: {
lineHeight: "normal",
},
listItem: {
padding: "0",
copyButton: {
width: theme.spacing(17),
},
copyButtonSuccess: {
marta- marked this conversation as resolved.
Show resolved Hide resolved
width: theme.spacing(17),
backgroundColor: theme.palette.success.light,
"&:hover,&:focus,&:visited,&": {
backgroundColor: theme.palette.success.main,
}
},
}));

const StyledTableCell = withStyles((theme) => ({
head: {
backgroundColor: theme.palette.action.hover,
padding: theme.spacing(1),
'&:nth-of-type(1)': {
width: theme.spacing(12),
},
'&:nth-of-type(2)': {
width: theme.spacing(8),
},
'&:nth-of-type(3)': {
width: theme.spacing(12),
},
'&:nth-of-type(4)': {
width: theme.spacing(63),
},
},
body: {
padding: theme.spacing(1),
},
}))(TableCell);

const StyledButton = withStyles((theme) => ({
label: {
textTransform: "none",
},
}))(Button);

const salt = "$2a$10$biRUcRBR1wroz1r45ORKs.";

// Health card number processing utils
Expand Down Expand Up @@ -227,6 +260,7 @@
const [ binput, setBinput ] = useState();
const [ projectId, setProjectId ] = useState(new URLSearchParams(window.location.search).get('project_id') || '');
const [ bhashes, setBhashes ] = useState({});
const [ copied, setCopied ] = useState(false);
const [ validatedData, setValidatedData ] = useState([]);
const [ dateFormat, setDateFormat ] = useState(DEFAULT_DATE_FORMAT);
const HC = 0, PROVINCE = 1, DOB = 2, COMPONENTS = 3;
Expand Down Expand Up @@ -283,6 +317,7 @@
let value = binput;
setBhashes({});
setValidatedData([]);
setCopied(false);

if (!value) return;

Expand All @@ -301,14 +336,14 @@
// There should be 3 pieces per each line: Health card #, Province code, Date of birth
let countErr = checkInfoCount(info);
if (countErr) {
postProcessed.push({"index": index, "value" : countErr, "isError": true});
postProcessed.push({"index": index, "info" : info.filter((item)=>true), "value" : countErr, "isError": true});
continue;
}

// Validate DOB
let date = validateDOB(info[DOB]);
if (date.error) {
postProcessed.push({"index": index, "value": date.error, "isError": true});
postProcessed.push({"index": index, "info" : info.filter((item)=>true), "value": date.error, "isError": true});
continue;
} else {
info[DOB] = date;
Expand All @@ -317,7 +352,7 @@
// Validate Province code
let province = validateProvince(info[PROVINCE]);
if (province.error) {
postProcessed.push({"index": index, "value": province.error, "isError": true});
postProcessed.push({"index": index, "info" : info.filter((item)=>true), "value": province.error, "isError": true});
continue;
} else {
info[PROVINCE] = province;
Expand All @@ -326,7 +361,7 @@
// Validate Health card number y province
let healthCard = validateHealthCard(info[HC], info[PROVINCE], info[DOB]);
if (healthCard.error) {
postProcessed.push({"index": index, "value": healthCard.error, "isError": true});
postProcessed.push({"index": index, "info" : info.filter((item)=>true), "value": healthCard.error, "isError": true});
continue;
} else {
info[HC] = healthCard;
Expand All @@ -335,7 +370,7 @@
// Check duplicated <health card, province> pair
let duplicates = checkDuplicates(info, postProcessed);
if (duplicates.error) {
postProcessed.push({"index": index, "value": duplicates.error, "isError": true});
postProcessed.push({"index": index, "info" : info.filter((item)=>true), "value": duplicates.error, "isError": true});
continue;
}

Expand Down Expand Up @@ -376,6 +411,13 @@
})
}

let onCopyButtonClick = () => {
setCopied(true);
setTimeout(function() {
setCopied(false);
}, 3000);
}

return (
<div className={classes.main}>
<Typography variant="h3">GUID generator</Typography>
Expand Down Expand Up @@ -430,9 +472,6 @@
className: classes.helperText
}}
/>
<FormHelperText style={{color: "red"}}>{ Object.keys(validatedData).map( item =>
<div>{validatedData[item].isError ? "Line " + (+item+1) + ": " + validatedData[item].value : ""}</div>
)}</FormHelperText>
</Grid>
<Grid item>
<TextField
Expand All @@ -456,17 +495,51 @@
/>
</Grid>
<Grid item>
<Button onClick={() => onSubmit()} variant="contained" color="primary" disabled={!(binput?.trim().length > 0)}>Generate GUIDs</Button>
<StyledButton onClick={() => onSubmit()} variant="contained" color="primary" disabled={!(binput?.trim().length > 0)}>Generate GUIDs</StyledButton>
</Grid>
</Grid>
{ Object.keys(bhashes).length > 0 &&
<List>
{ validatedData.map( item =>
<ListItem className={classes.listItem}>
<ListItemText primary={bhashes[item.index].value} style={{color: bhashes[item.index].isError ? 'red' : 'black'}} />
</ListItem>
)}
</List>
<TableContainer component={Paper}>
<Table size="small">
<TableHead>
<TableRow>
<StyledTableCell>Health card #</StyledTableCell>
<StyledTableCell>Province</StyledTableCell>
<StyledTableCell>Date of birth</StyledTableCell>
<StyledTableCell>
<Grid container direction="row" justify="space-between" alignItems="center">
<Grid item>GUID</Grid>
<Grid item>
<CopyToClipboard text={validatedData.map(item => item.isError ? '' : bhashes[item.index].value).join('\r\n')}
onCopy={() => onCopyButtonClick()}
options={{"format" : "text/plain", "debug" : true}}
marta- marked this conversation as resolved.
Show resolved Hide resolved
>
<StyledButton variant="contained"
color="default"
title={copied ? "GUIDs copied to clipboard" : "Copy all GUIDs to clipboard"}
className={copied ? classes.copyButtonSuccess : classes.copyButton}
startIcon={<Icon>{copied ? "check" : "file_copy"}</Icon>}>
{copied ? "Copied" : "Copy GUIDs"}
</StyledButton>
</CopyToClipboard>
</Grid>
</Grid>
</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{ validatedData.map( item =>
<TableRow key={item.index}>
<StyledTableCell>{item.info[HC]}</StyledTableCell>
<StyledTableCell>{item.info[PROVINCE]}</StyledTableCell>
<StyledTableCell>{item.info[DOB]}</StyledTableCell>
<StyledTableCell style={{color: bhashes[item.index].isError ? 'red' : 'black'}}>{bhashes[item.index].value}</StyledTableCell>
</TableRow>
)
}
</TableBody>
</Table>
</TableContainer>
}
</div>
);
Expand Down