From 0f328dfe03b8e4e6ac2a832abde5d9d3cbe3c3c3 Mon Sep 17 00:00:00 2001 From: Albin Henriksson <albhe428@student.liu.se> Date: Thu, 25 Feb 2021 11:10:17 +0100 Subject: [PATCH] Resolve "Add styling" --- client/.eslintrc | 2 + client/coverage_report.py | 12 +- client/package-lock.json | 253 +++++++++++++++++++++++++++++++- client/package.json | 3 +- client/src/App.tsx | 4 + client/src/components/Login.css | 10 ++ client/src/components/Login.tsx | 135 ++++++++++------- client/src/index.tsx | 1 - package-lock.json | 3 - 9 files changed, 355 insertions(+), 68 deletions(-) create mode 100644 client/src/components/Login.css delete mode 100644 package-lock.json diff --git a/client/.eslintrc b/client/.eslintrc index c0c40d69..46369ae6 100644 --- a/client/.eslintrc +++ b/client/.eslintrc @@ -28,8 +28,10 @@ "plugin:prettier/recommended" ], "rules": { + "semi": "off", "react/jsx-one-expression-per-line": "off", + "prettier/prettier": [ "error", { diff --git a/client/coverage_report.py b/client/coverage_report.py index c6cd3763..a464ba75 100644 --- a/client/coverage_report.py +++ b/client/coverage_report.py @@ -1,8 +1,10 @@ import xml.etree.ElementTree as et -tree = et.parse('output/coverage/jest/cobertura-coverage.xml') +tree = et.parse("output/coverage/jest/cobertura-coverage.xml") root = tree.getroot() -for package_class in tree.find('.//packages'): - package_class.set('name', 'client.' + package_class.attrib.get('name')) - package_class.set('filename', 'client/' + package_class.attrib.get('filename')) -tree.write('output/coverage/jest/cobertura-coverage.xml') +for package in tree.find(".//packages"): + package.set("name", "client." + package.attrib.get("name")) + for package_class in package.find("classes"): + package_class.set("name", "client." + package_class.attrib.get("name")) + package_class.set("filename", "client/" + package_class.attrib.get("filename")) +tree.write("output/coverage/jest/cobertura-coverage.xml") diff --git a/client/package-lock.json b/client/package-lock.json index ce26473a..67ccc686 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1125,6 +1125,11 @@ "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" }, + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, "@eslint/eslintrc": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", @@ -1729,6 +1734,100 @@ } } }, + "@material-ui/core": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz", + "integrity": "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw==", + "requires": { + "@babel/runtime": "^7.4.4", + "@material-ui/styles": "^4.11.3", + "@material-ui/system": "^4.11.3", + "@material-ui/types": "^5.1.0", + "@material-ui/utils": "^4.11.2", + "@types/react-transition-group": "^4.2.0", + "clsx": "^1.0.4", + "hoist-non-react-statics": "^3.3.2", + "popper.js": "1.16.1-lts", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0", + "react-transition-group": "^4.4.0" + } + }, + "@material-ui/lab": { + "version": "4.0.0-alpha.57", + "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.57.tgz", + "integrity": "sha512-qo/IuIQOmEKtzmRD2E4Aa6DB4A87kmY6h0uYhjUmrrgmEAgbbw9etXpWPVXuRK6AGIQCjFzV6WO2i21m1R4FCw==", + "requires": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.2", + "clsx": "^1.0.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + } + }, + "@material-ui/styles": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz", + "integrity": "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg==", + "requires": { + "@babel/runtime": "^7.4.4", + "@emotion/hash": "^0.8.0", + "@material-ui/types": "^5.1.0", + "@material-ui/utils": "^4.11.2", + "clsx": "^1.0.4", + "csstype": "^2.5.2", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.5.1", + "jss-plugin-camel-case": "^10.5.1", + "jss-plugin-default-unit": "^10.5.1", + "jss-plugin-global": "^10.5.1", + "jss-plugin-nested": "^10.5.1", + "jss-plugin-props-sort": "^10.5.1", + "jss-plugin-rule-value-function": "^10.5.1", + "jss-plugin-vendor-prefixer": "^10.5.1", + "prop-types": "^15.7.2" + }, + "dependencies": { + "csstype": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.15.tgz", + "integrity": "sha512-FNeiVKudquehtR3t9TRRnsHL+lJhuHF5Zn9dt01jpojlurLEPDhhEtUkWmAUJ7/fOLaLG4dCDEnUsR0N1rZSsg==" + } + } + }, + "@material-ui/system": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz", + "integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==", + "requires": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.2", + "csstype": "^2.5.2", + "prop-types": "^15.7.2" + }, + "dependencies": { + "csstype": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.15.tgz", + "integrity": "sha512-FNeiVKudquehtR3t9TRRnsHL+lJhuHF5Zn9dt01jpojlurLEPDhhEtUkWmAUJ7/fOLaLG4dCDEnUsR0N1rZSsg==" + } + } + }, + "@material-ui/types": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", + "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==" + }, + "@material-ui/utils": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz", + "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==", + "requires": { + "@babel/runtime": "^7.4.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", @@ -2328,6 +2427,14 @@ "@types/react-router": "*" } }, + "@types/react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-vIo69qKKcYoJ8wKCJjwSgCTM+z3chw3g18dkrDfVX665tMH7tmbDxEAnPdey4gTlwZz5QuHGzd+hul0OVZDqqQ==", + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", @@ -3741,11 +3848,6 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, - "bootstrap": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz", - "integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4165,6 +4267,11 @@ "wrap-ansi": "^6.2.0" } }, + "clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -4678,6 +4785,15 @@ } } }, + "css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "requires": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "css-what": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", @@ -5188,6 +5304,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", + "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -7666,6 +7791,11 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" }, + "hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -7766,6 +7896,14 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "indefinite-observable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz", + "integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==", + "requires": { + "symbol-observable": "1.2.0" + } + }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -7996,6 +8134,11 @@ "is-extglob": "^2.1.1" } }, + "is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" + }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -9810,6 +9953,85 @@ "verror": "1.10.0" } }, + "jss": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.5.1.tgz", + "integrity": "sha512-hbbO3+FOTqVdd7ZUoTiwpHzKXIo5vGpMNbuXH1a0wubRSWLWSBvwvaq4CiHH/U42CmjOnp6lVNNs/l+Z7ZdDmg==", + "requires": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "indefinite-observable": "^2.0.1", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-camel-case": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.5.1.tgz", + "integrity": "sha512-9+oymA7wPtswm+zxVti1qiowC5q7bRdCJNORtns2JUj/QHp2QPXYwSNRD8+D2Cy3/CEMtdJzlNnt5aXmpS6NAg==", + "requires": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.5.1" + } + }, + "jss-plugin-default-unit": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.5.1.tgz", + "integrity": "sha512-D48hJBc9Tj3PusvlillHW8Fz0y/QqA7MNmTYDQaSB/7mTrCZjt7AVRROExoOHEtd2qIYKOYJW3Jc2agnvsXRlQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1" + } + }, + "jss-plugin-global": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.5.1.tgz", + "integrity": "sha512-jX4XpNgoaB8yPWw/gA1aPXJEoX0LNpvsROPvxlnYe+SE0JOhuvF7mA6dCkgpXBxfTWKJsno7cDSCgzHTocRjCQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1" + } + }, + "jss-plugin-nested": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.5.1.tgz", + "integrity": "sha512-xXkWKOCljuwHNjSYcXrCxBnjd8eJp90KVFW1rlhvKKRXnEKVD6vdKXYezk2a89uKAHckSvBvBoDGsfZrldWqqQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-props-sort": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.5.1.tgz", + "integrity": "sha512-t+2vcevNmMg4U/jAuxlfjKt46D/jHzCPEjsjLRj/J56CvP7Iy03scsUP58Iw8mVnaV36xAUZH2CmAmAdo8994g==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1" + } + }, + "jss-plugin-rule-value-function": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.5.1.tgz", + "integrity": "sha512-3gjrSxsy4ka/lGQsTDY8oYYtkt2esBvQiceGBB4PykXxHoGRz14tbCK31Zc6DHEnIeqsjMUGbq+wEly5UViStQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-vendor-prefixer": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.5.1.tgz", + "integrity": "sha512-cLkH6RaPZWHa1TqSfd2vszNNgxT1W0omlSjAd6hCFHp3KIocSrW21gaHjlMU26JpTHwkc+tJTCQOmE/O1A4FKQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.5.1" + } + }, "jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -11206,6 +11428,11 @@ "ts-pnp": "^1.1.6" } }, + "popper.js": { + "version": "1.16.1-lts", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", + "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==" + }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -12862,6 +13089,17 @@ } } }, + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -14613,6 +14851,11 @@ "util.promisify": "~1.0.0" } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/client/package.json b/client/package.json index a882fac0..4fcc3e71 100644 --- a/client/package.json +++ b/client/package.json @@ -3,6 +3,8 @@ "version": "0.1.0", "private": true, "dependencies": { + "@material-ui/core": "^4.11.3", + "@material-ui/lab": "^4.0.0-alpha.57", "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^12.6.3", @@ -11,7 +13,6 @@ "@types/react": "^17.0.1", "@types/react-dom": "^17.0.0", "axios": "^0.21.1", - "bootstrap": "^4.6.0", "formik": "^2.2.6", "react": "^17.0.1", "react-dom": "^17.0.1", diff --git a/client/src/App.tsx b/client/src/App.tsx index a48b2037..2df0f43f 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -7,6 +7,10 @@ import TestConnection from './components/TestConnection' const App: React.FC = () => { return ( <div className="wrapper"> + <link + rel="stylesheet" + href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" + /> <h1>Application</h1> <TestConnection /> <BrowserRouter> diff --git a/client/src/components/Login.css b/client/src/components/Login.css new file mode 100644 index 00000000..5a01047d --- /dev/null +++ b/client/src/components/Login.css @@ -0,0 +1,10 @@ +.login-page { + display: flex; + justify-content: center; +} + +.login-form { + display: flex; + flex-direction: column; + width: 250px; +} diff --git a/client/src/components/Login.tsx b/client/src/components/Login.tsx index 0cf6a02c..75123ff3 100644 --- a/client/src/components/Login.tsx +++ b/client/src/components/Login.tsx @@ -1,9 +1,14 @@ +import { Button, TextField } from '@material-ui/core' +import { withStyles } from '@material-ui/core/styles' +import { Alert, AlertTitle } from '@material-ui/lab' import axios from 'axios' -import 'bootstrap/dist/css/bootstrap.min.css' -import { ErrorMessage, Field, Form, Formik } from 'formik' +import { Formik, FormikHelpers } from 'formik' import React, { useState } from 'react' import * as Yup from 'yup' import { LoginModel } from '../interfaces/models' +import './Login.css' + +const styles = {} interface LoginState { status: number @@ -15,6 +20,11 @@ interface LoginFormModel { error?: string } +interface ServerResponse { + code: number + message: string +} + const schema: Yup.SchemaOf<LoginFormModel> = Yup.object({ model: Yup.object() .shape({ @@ -29,63 +39,82 @@ const schema: Yup.SchemaOf<LoginFormModel> = Yup.object({ error: Yup.string().optional() }) -const LoginForm: React.FC = () => { +const handleSubmit = async ( + values: LoginFormModel, + actions: FormikHelpers<LoginFormModel> +) => { + await axios + .post<ServerResponse>(`users/login`, values.model) + .then((res) => { + actions.resetForm() + }) + .catch(({ response }) => { + actions.setFieldError('error', response.data.message) + }) + .finally(() => { + actions.setSubmitting(false) + }) +} + +const LoginForm: React.FC = (props) => { const [serverState, setServerState] = useState<LoginFormModel>() const initialValues: LoginFormModel = { model: { email: '', password: '' } } return ( - <Formik - initialValues={initialValues} - validationSchema={schema} - onSubmit={async (values, actions) => { - await axios - .post(`users/login`, values.model) - .then((res) => { - actions.resetForm() - }) - .catch((error) => { - actions.setFieldError('error', 'Invalid email or password') - }) - .finally(() => { - actions.setSubmitting(false) - }) - }} - > - {(formik) => ( - <Form> - <div className="form-group"> - <label htmlFor="model.email">Email Address</label> - <Field name="model.email" type="email" className="form-control" /> - <ErrorMessage name="model.email"> - {(msg) => <div className="text-danger">{msg}</div>} - </ErrorMessage> - </div> - - <div className="form-group"> - <label htmlFor="model.password">Password</label> - <Field + <div className="login-page"> + <Formik + initialValues={initialValues} + validationSchema={schema} + onSubmit={handleSubmit} + > + {(formik) => ( + <form onSubmit={formik.handleSubmit} className="login-form"> + <TextField + label="Email Address" + name="model.email" + helperText={ + formik.touched.model?.email ? formik.errors.model?.email : '' + } + error={Boolean(formik.errors.model?.email)} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + margin="normal" + /> + <TextField + label="Password" name="model.password" type="password" - className="form-control" + helperText={ + formik.touched.model?.password + ? formik.errors.model?.password + : '' + } + error={Boolean(formik.errors.model?.password)} + onChange={formik.handleChange} + onBlur={formik.handleBlur} + margin="normal" /> - <ErrorMessage name="model.password"> - {(msg) => <div className="text-danger">{msg}</div>} - </ErrorMessage> - </div> - - <div className="form-group"> - <button type="submit" className="btn btn-primary"> - Login - </button> - </div> - <div className="form-group"> - <ErrorMessage name="error"> - {(msg) => <div className="text-danger">{msg}</div>} - </ErrorMessage> - </div> - </Form> - )} - </Formik> + <Button + type="submit" + fullWidth + variant="contained" + color="primary" + disabled={!formik.isValid} + > + Submit + </Button> + {formik.errors.error ? ( + <Alert severity="error"> + <AlertTitle>Error</AlertTitle> + {formik.errors.error} + </Alert> + ) : ( + <div /> + )} + </form> + )} + </Formik> + </div> ) } -export default LoginForm +export default withStyles(styles)(LoginForm) diff --git a/client/src/index.tsx b/client/src/index.tsx index 728ad9bd..e7b11a23 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -1,4 +1,3 @@ -import 'bootstrap/dist/css/bootstrap.min.css' import React from 'react' import ReactDOM from 'react-dom' import App from './App' diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 48e341a0..00000000 --- a/package-lock.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "lockfileVersion": 1 -} -- GitLab