Skip to content

Commit

Permalink
feat(create secret): create secret implementation view (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
elysee15 authored Aug 4, 2021
1 parent 6c341c8 commit 472674e
Show file tree
Hide file tree
Showing 13 changed files with 463 additions and 66 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"react/jsx-filename-extension": [ "warn", {"extensions": [".ts",".tsx"]} ],
"no-shadow": "off",
"no-console":1,
"@typescript-eslint/no-shadow": ["error"]
"@typescript-eslint/no-shadow": ["error"],
"react/prop-types": "off"
},
"settings": {
"react": {
Expand Down
62 changes: 35 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"private": true,
"dependencies": {
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.60",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
Expand All @@ -12,12 +14,18 @@
"@types/react": "^17.0.15",
"@types/react-dom": "^17.0.9",
"axios": "^0.21.1",
"clsx": "^1.1.1",
"formik": "^2.2.9",
"formik-material-ui": "^3.0.1",
"formik-material-ui-lab": "^0.0.8",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"react-select": "^4.3.1",
"typescript": "^4.3.5",
"web-vitals": "^1.0.1"
"web-vitals": "^1.0.1",
"yup": "^0.32.9"
},
"scripts": {
"start": "react-scripts start",
Expand All @@ -26,11 +34,11 @@
"eject": "react-scripts eject",
"lint": "npx eslint \"**/*.{ts, tsx}\"",
"lint:fix": "npx eslint \"**/*.{ts, tsx}\" --fix",
"prettier:fix": "prettier --write \"**/*.{ts, tsx}\"",
"prettier:fix": "prettier --write \"**/*.{ts, tsx}\"",
"prettier": "npx prettier \"**/*.{ts, tsx}\"",
"prettier:write": "npx prettier -w \"**/*.{ts, tsx}\"",
"commit": "cz",
"precommit": "npm run lint && npm run prettier:fix",
"commit": "cz",
"precommit": "npm run lint && npm run prettier:fix",
"release": "standard-version"
},
"eslintConfig": {
Expand All @@ -55,6 +63,7 @@
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"@types/react-router-dom": "^5.1.8",
"@types/react-select": "^4.0.17",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"cz-conventional-changelog": "3.3.0",
Expand All @@ -66,27 +75,26 @@
"prettier": "2.3.2",
"standard-version": "^9.3.1"
},
"standard-version": {
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
"prettier --single-quote --write"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
"standard-version": {},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
"prettier --single-quote --write"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
3 changes: 1 addition & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import AppRouter from "Router";
import { BrowserRouter as Router } from "react-router-dom";
import AppRouter from "routes";
import "./App.css";

const App: React.FC = () => {
return (
<Router>
<div className="App">
Render
<AppRouter />
</div>
</Router>
Expand Down
14 changes: 0 additions & 14 deletions src/Router.tsx

This file was deleted.

172 changes: 172 additions & 0 deletions src/components/CreateSecretForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { Button, makeStyles, Theme, Typography } from "@material-ui/core";
import { TextField, Switch } from "formik-material-ui";
import { Field, Form, Formik } from "formik";
import { Autocomplete, AutocompleteRenderInputParams } from "formik-material-ui-lab";
import { TextField as MuiTextField } from "@material-ui/core";
import * as Yup from "yup";
import { Lifetime } from "utils/interfaces";
import { useEffect } from "react";

const useStyles = makeStyles((theme: Theme) => ({
form: {
display: "flex",
flexDirection: "column",
gap: theme.spacing(2),
maxWidth: 400,
margin: "auto",
"& .MuiTextField-root": {
width: "100%"
}
},
height__full: {
height: "100%"
},
hide: {
display: "none"
}
}));

const options: Lifetime[] = [
{ value: "5m", label: "5 min" },
{ value: "15m", label: "15 min" },
{ value: "30m", label: "30 min" },
{ value: "1h", label: "1 hour" },
{ value: "2h", label: "2 hours" },
{ value: "3h", label: "3 hours" },
{ value: "24h", label: "1 day" },
{ value: "48h", label: "2 days" },
{ value: "72h", label: "3 days" },
{ value: "168h", label: "7 days" }
];

const initialValues = {
secret: "",
password: "",
accessType: true,
accessNumber: 1,
lifetime: { value: "7d", label: "7 days" }
};

const CreateSecretSchema = Yup.object().shape({
secret: Yup.string().required("You must add a secret"),
password: Yup.string(),
lifetime: Yup.object().shape({ value: Yup.string(), label: Yup.string() }).nullable(),
accessType: Yup.boolean(),
accessNumber: Yup.number().max(108, "The max number is 108")
});

const CreateSecretForm: React.FC = () => {
const classes = useStyles();

function preventNonNumericalInput(e: any) {
e = e || window.event;
const charCode = typeof e.which == "undefined" ? e.keyCode : e.which;
const charStr = String.fromCharCode(charCode);

if (!charStr.match(/^[0-9]+$/)) e.preventDefault();
}

return (
<Formik
initialValues={initialValues}
validationSchema={CreateSecretSchema}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
setSubmitting(false);
alert(JSON.stringify(values, null, 2));
}, 200);
}}
>
{({ isSubmitting, errors, values, setFieldValue }) => {
useEffect(() => {
if (values.accessType) {
setFieldValue("accessNumber", -1);
} else {
setFieldValue("accessNumber", 1);
}
}, [values.accessType]);

return (
<Form className={classes.form} noValidate>
<div>
<Field
component={TextField}
name="secret"
type="text"
label="Type your secret here"
variant="outlined"
placeholder="Type your secret here"
required
multiline
minRows={10}
maxRows={15}
/>
</div>
<div>
<Field
component={TextField}
type="password"
label="Your secret password"
name="password"
size="small"
variant="outlined"
disabled
/>
</div>
<div>
<Field component={Switch} type="checkbox" name="accessType" />
<Typography variant="button">unlimited access</Typography>
</div>
<div className={values["accessType"] ? classes.hide : undefined}>
<Field
component={TextField}
type="number"
label="Number of access"
name="accessNumber"
size="small"
variant="outlined"
pattern="[0-9]*"
InputProps={{ inputProps: { min: 1, max: 108 } }}
onKeyPress={preventNonNumericalInput}
onInput={(e: any) => {
e.target.value = Math.max(-1, parseInt(e.target.value)).toString().slice(0, 3);
}}
/>
</div>
<div>
<Field
name="lifetime"
component={Autocomplete}
size="small"
options={options}
disabled
getOptionLabel={(option: Lifetime) => option.label}
getOptionSelected={(option: Lifetime, value: Lifetime) => option.value === value.value}
renderInput={(params: AutocompleteRenderInputParams) => (
<MuiTextField
{...params}
label="Secret lifetime"
variant="outlined"
error={!!errors["lifetime"]}
helperText={
errors["lifetime"]
? errors["lifetime"]
: "By default, the secret has 7 days before being destroyed"
}
/>
)}
/>
</div>
<div>
<Button type="submit" variant="contained" color="primary" disabled={isSubmitting}>
Get Token
</Button>
</div>
</Form>
);
}}
</Formik>
);
};

export default CreateSecretForm;
33 changes: 33 additions & 0 deletions src/pages/CreateSecret.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import { Grid, makeStyles, Theme } from "@material-ui/core";
import CreateSecretForm from "components/CreateSecretForm";

const useStyles = makeStyles((theme: Theme) => ({
root: {
flexGrow: 1,
height: "100vh",
padding: theme.spacing(2)
},
h__full: {
height: "100%"
},
w__full: {
width: "100%"
}
}));

const CreateSecret: React.FC = () => {
const classes = useStyles();

return (
<div className={classes.root}>
<Grid container alignItems="center" className={classes.h__full}>
<Grid item sm={12} md={12} className={classes.w__full}>
<CreateSecretForm />
</Grid>
</Grid>
</div>
);
};

export default CreateSecret;
5 changes: 0 additions & 5 deletions src/pages/Example.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as Example } from "./Example";
export { default as CreateSecret } from "./CreateSecret";
13 changes: 13 additions & 0 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import { Route, Switch } from "react-router-dom";
import CreateSecret from "pages/CreateSecret";

const AppRouter: React.FC = () => {
return (
<Switch>
<Route path="/" component={CreateSecret} />
</Switch>
);
};

export default AppRouter;
10 changes: 3 additions & 7 deletions src/theme/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { createTheme, responsiveFontSizes } from "@material-ui/core";
import { green, purple } from "@material-ui/core/colors";
import { green, indigo } from "@material-ui/core/colors";

const theme = createTheme({
palette: {
primary: {
main: purple[500]
},
secondary: {
main: green[500]
}
primary: indigo,
secondary: green
}
});

Expand Down
4 changes: 4 additions & 0 deletions src/utils/interfaces/Lifetime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface Lifetime {
label: string;
value: string;
}
1 change: 1 addition & 0 deletions src/utils/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Lifetime";
Loading

0 comments on commit 472674e

Please sign in to comment.