mirror of
https://github.com/SomboChea/ui
synced 2024-11-17 03:34:27 +07:00
e6b53c0479
* chore: migrate to eslint6 * chore: migrate to eslint6
188 lines
4.7 KiB
TypeScript
188 lines
4.7 KiB
TypeScript
import React, { Component, ReactElement } from 'react';
|
|
import isNil from 'lodash/isNil';
|
|
import 'normalize.css';
|
|
import 'typeface-roboto/index.css';
|
|
|
|
import storage from '../utils/storage';
|
|
import { makeLogin, isTokenExpire } from '../utils/login';
|
|
import Loading from '../components/Loading';
|
|
import LoginModal from '../components/Login';
|
|
import Header from '../components/Header';
|
|
import { Container, Content } from '../components/Layout';
|
|
import API from '../utils/api';
|
|
import '../utils/styles/global';
|
|
import Footer from '../components/Footer';
|
|
|
|
import AppRoute from './AppRoute';
|
|
import { AppProps, AppContextProvider } from './AppContext';
|
|
|
|
export default class App extends Component<{}, AppProps> {
|
|
public state: AppProps = {
|
|
logoUrl: window.VERDACCIO_LOGO,
|
|
user: {},
|
|
scope: window.VERDACCIO_SCOPE || '',
|
|
showLoginModal: false,
|
|
isUserLoggedIn: false,
|
|
packages: [],
|
|
isLoading: true,
|
|
};
|
|
|
|
public componentDidMount(): void {
|
|
this.isUserAlreadyLoggedIn();
|
|
this.loadOnHandler();
|
|
}
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
public componentDidUpdate(_: AppProps, prevState: AppProps): void {
|
|
const { isUserLoggedIn } = this.state;
|
|
if (prevState.isUserLoggedIn !== isUserLoggedIn) {
|
|
this.loadOnHandler();
|
|
}
|
|
}
|
|
|
|
public render(): React.ReactElement<HTMLDivElement> {
|
|
const { isLoading, isUserLoggedIn, packages, logoUrl, user, scope } = this.state;
|
|
|
|
const context = { isUserLoggedIn, packages, logoUrl, user, scope };
|
|
|
|
return (
|
|
<Container isLoading={isLoading}>
|
|
{isLoading ? <Loading /> : <AppContextProvider value={context}>{this.renderContent()}</AppContextProvider>}
|
|
{this.renderLoginModal()}
|
|
</Container>
|
|
);
|
|
}
|
|
|
|
public isUserAlreadyLoggedIn = () => {
|
|
// checks for token validity
|
|
const token = storage.getItem('token');
|
|
const username: string = storage.getItem('username') as string;
|
|
if (isTokenExpire(token) || isNil(username)) {
|
|
this.handleLogout();
|
|
} else {
|
|
this.setState({
|
|
user: { username },
|
|
isUserLoggedIn: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
public loadOnHandler = async () => {
|
|
try {
|
|
const packages = await API.request<any[]>('packages', 'GET');
|
|
// @ts-ignore: FIX THIS TYPE: Type 'any[]' is not assignable to type '[]'
|
|
this.setState({
|
|
packages,
|
|
isLoading: false,
|
|
});
|
|
} catch (error) {
|
|
// FIXME: add dialog
|
|
console.error({
|
|
title: 'Warning',
|
|
message: `Unable to load package list: ${error.message}`,
|
|
});
|
|
this.setLoading(false);
|
|
}
|
|
};
|
|
|
|
public setLoading = (isLoading: boolean) =>
|
|
this.setState({
|
|
isLoading,
|
|
});
|
|
|
|
/**
|
|
* Toggles the login modal
|
|
* Required by: <LoginModal /> <Header />
|
|
*/
|
|
public handleToggleLoginModal = () => {
|
|
this.setState(prevState => ({
|
|
showLoginModal: !prevState.showLoginModal,
|
|
}));
|
|
};
|
|
|
|
/**
|
|
* handles login
|
|
* Required by: <Header />
|
|
*/
|
|
public handleDoLogin = async (usernameValue: string, passwordValue: string) => {
|
|
const { username, token, error } = await makeLogin(usernameValue, passwordValue);
|
|
|
|
if (username && token) {
|
|
storage.setItem('username', username);
|
|
storage.setItem('token', token);
|
|
this.setLoggedUser(username);
|
|
}
|
|
|
|
if (error) {
|
|
this.setState({
|
|
user: {},
|
|
error,
|
|
});
|
|
}
|
|
};
|
|
|
|
public setLoggedUser = (username: string) => {
|
|
this.setState({
|
|
user: {
|
|
username,
|
|
},
|
|
isUserLoggedIn: true, // close login modal after successful login
|
|
showLoginModal: false, // set isUserLoggedIn to true
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Logouts user
|
|
* Required by: <Header />
|
|
*/
|
|
public handleLogout = () => {
|
|
storage.removeItem('username');
|
|
storage.removeItem('token');
|
|
this.setState({
|
|
user: {},
|
|
isUserLoggedIn: false,
|
|
});
|
|
};
|
|
|
|
public renderLoginModal = (): ReactElement<HTMLElement> => {
|
|
const { error, showLoginModal } = this.state;
|
|
return (
|
|
<LoginModal
|
|
error={error}
|
|
onCancel={this.handleToggleLoginModal}
|
|
onSubmit={this.handleDoLogin}
|
|
visibility={showLoginModal}
|
|
/>
|
|
);
|
|
};
|
|
|
|
public renderContent = (): ReactElement<HTMLElement> => {
|
|
return (
|
|
<>
|
|
<Content>
|
|
<AppRoute>{this.renderHeader()}</AppRoute>
|
|
</Content>
|
|
<Footer />
|
|
</>
|
|
);
|
|
};
|
|
|
|
public renderHeader = (): ReactElement<HTMLElement> => {
|
|
const {
|
|
logoUrl,
|
|
user: { username },
|
|
scope,
|
|
} = this.state;
|
|
|
|
return (
|
|
<Header
|
|
logo={logoUrl}
|
|
onLogout={this.handleLogout}
|
|
onToggleLoginModal={this.handleToggleLoginModal}
|
|
scope={scope}
|
|
username={username}
|
|
/>
|
|
);
|
|
};
|
|
}
|