feat: First implementation

This commit is contained in:
Alexander Polynomdivision 2018-08-24 19:03:08 +02:00
parent 7748939c65
commit 297d2e50f9
10 changed files with 9799 additions and 1187 deletions

10687
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,11 +4,22 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1",
"start": "parcel src/index.html --public-url '/'"
}, },
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"lite-server": "^2.4.0" "@material-ui/core": "^1.5.1",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-router-dom": "^4.3.1"
},
"devDependencies": {
"html-webpack-plugin": "3.2.0",
"typescript": "^2.9.2",
"webpack": "4.17.1",
"webpack-cli": "3.1.0",
"parcel-bundler": "^1.9.7"
} }
} }

View File

@ -16,11 +16,11 @@ body {
width: 1920px; width: 1920px;
height: 1080px; height: 1080px;
-webkit-filter: blur(5px); -webkit-filter: blur(10px);
-moz-filter: blur(5px); -moz-filter: blur(10px);
-o-filter: blur(5px); -o-filter: blur(10px);
-ms-filter: blur(5px); -ms-filter: blur(10px);
filter: blur(5px); filter: blur(10px);
} }
.content { .content {

44
src/components/app.tsx Normal file
View File

@ -0,0 +1,44 @@
import * as React from "react";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import LoginPage from "../pages/login";
interface IState {
loggedIn: boolean;
}
export default class Application extends React.Component<{}, IState> {
constructor(props: any) {
super(props);
this.state = {
loggedIn: false,
};
this.login = this.login.bind(this);
}
login(username: string, password: string): Promise<boolean> {
return new Promise((res, rej) => {
// TODO
res();
});
}
render() {
return <div className="flex">
<AppBar position="static">
<Toolbar>
<Typography className="flex" variant="title" color="inherit">
Lateinicus
</Typography>
</Toolbar>
</AppBar>
<LoginPage login={this.login} />
</div>;
}
};

View File

@ -0,0 +1,7 @@
import * as React from "react";
export default class Loader extends React.Component<{}> {
render() {
return <div className="loader" />;
}
}

30
src/index.css Normal file
View File

@ -0,0 +1,30 @@
body {
margin: 0px;
z-index: 1;
}
.flex {
flex-grow: 1;
}
.toolbarLoginBtn {
margin-left: -12px;
margin-right: 20px;
}
.flex-parent {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.paper {
padding: 12px;
}
.login-btn {
width: 100%;
}

20
src/index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no"
/>
<link rel="stylesheet" href="./index.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
</head>
<body>
<div id="app"></div>
<script src="./index.tsx"></script>
</body>
</html>

6
src/index.tsx Normal file
View File

@ -0,0 +1,6 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import Application from "./components/app";
ReactDOM.render(<Application />, document.getElementById("app"));

126
src/pages/login.tsx Normal file
View File

@ -0,0 +1,126 @@
import * as React from "react";
import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";
import Button from "@material-ui/core/Button";
import LinearProgress from "@material-ui/core/LinearProgress";
import Snackbar from "@material-ui/core/Snackbar";
interface IProps {
login: (username: string, password: string) => Promise<boolean>;
}
interface IState {
username: string;
password: string;
loading: boolean;
snack: string; // The message
open: boolean;
}
export default class LoginPage extends React.Component<{}, IState> {
constructor(props: any) {
super(props);
this.state = {
username: "",
password: "",
loading: false;
snack: "",
open: false,
};
this.update = this.update.bind(this);
this.performLogin = this.performLogin.bind(this);
}
update(prop: string) {
return (event: any) => {
this.setState({
[prop]: event.target.value,
});
};
}
performLogin() {
const load = (loading) => {
this.setState({
loading
});
}
const showSnackbar = (msg) => {
this.setState({
open: true,
snack: msg,
});
};
load(true);
const { username, password } = this.state;
this.props.login(username, password).then((res) => {
load(false);
}, (err) => {
load(false);
showSnackbar("Failed to log in");
});
}
render() {
const snackbarClose = () => {
this.setState({ open: false });
};
return <div>
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justify="center"
style={{ minHeight: '100vh' }}>
<Grid item xs={12}>
<Paper className="paper">
<Typography variant="title">Login</Typography>
<Grid container direction="column" spacing={8}>
<Grid item>
<TextField
label="Username"
onChange={(ev) => this.update("username")} />
</Grid>
<Grid item>
<TextField
label="Passwort"
type="password"
onChange={(ev) => this.update("password")} />
</Grid>
<Grid item>
<Button
variant="contained"
color="primary"
className="login-btn"
onClick={() => this.performLogin()}>
Login
</Button>
{
this.state.loading ? (
<LinearProgress />
) : undefined
}
</Grid>
</Grid>
</Paper>
</Grid>
</Grid>
<Snackbar
open={this.state.open}
onClose={snackbarClose}
message={this.state.snack}
autoHideDuration={6000} />
</div>;
}
};

29
tsconfig.json Normal file
View File

@ -0,0 +1,29 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "commonjs",
"target": "es6",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
},
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"**/__test__/",
"src/setupTests.ts"
]
}