Alex Mikhalev
7 years ago
19 changed files with 262 additions and 130 deletions
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
import { AppState, injectState } from "@app/state"; |
||||
import log from "@common/logger"; |
||||
import { computed, observable } from "mobx"; |
||||
import { observer } from "mobx-react"; |
||||
import * as React from "react"; |
||||
import { Container, Dimmer, Form, Header, InputOnChangeData, Loader, Segment } from "semantic-ui-react"; |
||||
|
||||
class LoginPageState { |
||||
@observable username = ""; |
||||
@observable password = ""; |
||||
|
||||
@observable loading: boolean = false; |
||||
|
||||
@computed get canLogin() { |
||||
return this.username.length > 0 && this.password.length > 0; |
||||
} |
||||
|
||||
onUsernameChange = (e: any, data: InputOnChangeData) => { |
||||
this.username = data.value; |
||||
} |
||||
|
||||
onPasswordChange = (e: any, data: InputOnChangeData) => { |
||||
this.password = data.value; |
||||
} |
||||
|
||||
login(appState: AppState) { |
||||
this.loading = true; |
||||
appState.httpApi.tokenStore.grantPassword(this.username, this.password) |
||||
.then(() => { |
||||
this.loading = false; |
||||
log.info("logged in"); |
||||
appState.history.push("/"); |
||||
}) |
||||
.catch((err) => { |
||||
this.loading = false; |
||||
log.error({ err }, "login error"); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
class LoginPage extends React.Component<{ appState: AppState }> { |
||||
pageState = new LoginPageState(); |
||||
|
||||
render() { |
||||
const { username, password, canLogin, loading } = this.pageState; |
||||
return ( |
||||
<Container className="loginPage"> |
||||
<Segment> |
||||
<Dimmer inverted active={loading}> |
||||
<Loader/> |
||||
</Dimmer> |
||||
|
||||
<Header as="h1">Login</Header> |
||||
<Form> |
||||
<Form.Input label="Username" value={username} onChange={this.pageState.onUsernameChange}/> |
||||
<Form.Input |
||||
label="Password" |
||||
value={password} |
||||
type="password" |
||||
onChange={this.pageState.onPasswordChange} |
||||
/> |
||||
<Form.Button disabled={!canLogin} onClick={this.login}>Login</Form.Button> |
||||
</Form> |
||||
</Segment> |
||||
</Container> |
||||
); |
||||
} |
||||
|
||||
login = () => { |
||||
this.pageState.login(this.props.appState); |
||||
} |
||||
} |
||||
|
||||
const DecoratedLoginPage = injectState(observer(LoginPage)); |
||||
export { DecoratedLoginPage as LoginPage }; |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
import * as React from "react"; |
||||
import { RouteComponentProps } from "react-router"; |
||||
|
||||
import { DevicesView, MessageTest} from "@app/components"; |
||||
|
||||
export { LoginPage } from "./LoginPage"; |
||||
|
||||
export function DevicePage({ match }: RouteComponentProps<{ deviceId: string }>) { |
||||
return ( |
||||
<DevicesView deviceId={match.params.deviceId}/> |
||||
); |
||||
} |
||||
|
||||
export function MessagesTestPage() { |
||||
return ( |
||||
<MessageTest/> |
||||
); |
||||
} |
@ -1,26 +1,28 @@
@@ -1,26 +1,28 @@
|
||||
import { WebSocketApiClient } from "@app/sprinklersRpc/websocketClient"; |
||||
import { WebSocketRpcClient } from "@app/sprinklersRpc/websocketClient"; |
||||
import HttpApi from "@app/state/HttpApi"; |
||||
import { UiStore } from "@app/state/UiStore"; |
||||
import { createBrowserHistory, History } from "history"; |
||||
|
||||
const isDev = process.env.NODE_ENV === "development"; |
||||
const websocketPort = isDev ? 8080 : location.port; |
||||
|
||||
export default class ClientState { |
||||
sprinklersApi = new WebSocketApiClient(`ws://${location.hostname}:${websocketPort}`); |
||||
export default class AppState { |
||||
history: History = createBrowserHistory(); |
||||
uiStore = new UiStore(); |
||||
httpApi = new HttpApi(); |
||||
tokenStore = this.httpApi.tokenStore; |
||||
sprinklersRpc = new WebSocketRpcClient(`ws://${location.hostname}:${websocketPort}`, |
||||
this.tokenStore); |
||||
|
||||
async start() { |
||||
if (!this.httpApi.tokenStore.accessToken.isValid) { |
||||
if (this.httpApi.tokenStore.refreshToken.isValid) { |
||||
await this.httpApi.tokenStore.grantRefresh(); |
||||
} else { |
||||
await this.httpApi.tokenStore.grantPassword("alex", "kakashka"); |
||||
this.history.push("/login"); |
||||
} |
||||
} |
||||
|
||||
this.sprinklersApi.accessToken = this.httpApi.tokenStore.accessToken.token!; |
||||
|
||||
this.sprinklersApi.start(); |
||||
this.sprinklersRpc.start(); |
||||
} |
||||
} |
@ -1,9 +1,3 @@
@@ -1,9 +1,3 @@
|
||||
export { UiMessage, UiStore } from "./UiStore"; |
||||
export * from "./reactContext"; |
||||
export { ClientState as StateBase } from "./ClientState"; |
||||
|
||||
import ClientState from "./ClientState"; |
||||
|
||||
|
||||
export class WebApiState extends ClientState { |
||||
} |
||||
export { default as AppState } from "./AppState"; |
||||
|
Loading…
Reference in new issue