12 StayBooking Client 2
12 StayBooking Client 2
Layout and Authentication
src/App.js
import { Layout, Dropdown, Menu, Button } from "antd";
import { UserOutlined } from "@ant-design/icons";
import React from "react";
const { Header, Content } = Layout;
class App extends React.Component {
state = {
authed: false,
asHost: false,
};
componentDidMount() {
const authToken = localStorage.getItem("authToken");
const asHost = localStorage.getItem("asHost") === "true";
this.setState({
authed: authToken !== null,
asHost,
});
}
handleLoginSuccess = (token, asHost) => {
localStorage.setItem("authToken", token);
localStorage.setItem("asHost", asHost);
this.setState({
authed: true,
asHost,
});
};
handleLogOut = () => {
localStorage.removeItem("authToken");
localStorage.removeItem("asHost");
this.setState({
authed: false,
});
};
renderContent = () => {
if (!this.state.authed) {
return <div>login page</div>;
}
if (this.state.asHost) {
return <div>host home page</div>;
}
return <div>guest home page</div>;
};
userMenu = (
<Menu>
<Menu.Item key="logout" onClick={this.handleLogOut}>
Log Out
</Menu.Item>
</Menu>
);
render() {
return (
<Layout style={{ height: "100vh" }}>
<Header style={{ display: "flex", justifyContent: "space-between" }}>
<div style={{ fontSize: 16, fontWeight: 600, color: "white" }}>
Stays Booking
</div>
{this.state.authed && (
<div>
<Dropdown trigger="click" overlay={this.userMenu}>
<Button icon={<UserOutlined />} shape="circle" />
</Dropdown>
</div>
)}
</Header>
<Content
style={{ height: "calc(100% - 64px)", margin: 20, overflow: "auto" }}
>
{this.renderContent()}
</Content>
</Layout>
);
}
}
export default App;
Build the login Page
src/components/LoginPage.js
import React from "react";
import { Form, Button, Input, Space, Checkbox, message } from "antd";
import { UserOutlined } from "@ant-design/icons";
import { login, register } from "../utils";
class LoginPage extends React.Component {
formRef = React.createRef();
state = {
asHost: false,
loading: false,
};
onFinish = () => {
console.log("finish form");
};
handleLogin = async () => {
const formInstance = this.formRef.current;
try {
await formInstance.validateFields();
} catch (error) {
return;
}
this.setState({
loading: true,
});
try {
const { asHost } = this.state;
const resp = await login(formInstance.getFieldsValue(true), asHost);
this.props.handleLoginSuccess(resp.token, asHost);
} catch (error) {
message.error(error.message);
} finally {
this.setState({
loading: false,
});
}
};
handleRegister = async () => {
const formInstance = this.formRef.current;
try {
await formInstance.validateFields();
} catch (error) {
return;
}
this.setState({
loading: true,
});
try {
await register(formInstance.getFieldsValue(true), this.state.asHost);
message.success("Register Successfully");
} catch (error) {
message.error(error.message);
} finally {
this.setState({
loading: false,
});
}
};
handleCheckboxOnChange = (e) => {
this.setState({
asHost: e.target.checked,
});
};
render() {
return (
<div style={{ width: 500, margin: "20px auto" }}>
<Form ref={this.formRef} onFinish={this.onFinish}>
<Form.Item
name="username"
rules={[
{
required: true,
message: "Please input your Username!",
},
]}
>
<Input
disabled={this.state.loading}
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder="Username"
/>
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: "Please input your Password!",
},
]}
>
<Input.Password
disabled={this.state.loading}
placeholder="Password"
/>
</Form.Item>
</Form>
<Space>
<Checkbox
disabled={this.state.loading}
checked={this.state.asHost}
onChange={this.handleCheckboxOnChange}
>
As Host
</Checkbox>
<Button
onClick={this.handleLogin}
disabled={this.state.loading}
shape="round"
type="primary"
>
Log in
</Button>
<Button
onClick={this.handleRegister}
disabled={this.state.loading}
shape="round"
type="primary"
>
Register
</Button>
</Space>
</div>
);
}
}
export default LoginPage;
Then remember to replace the “login page” placeholder with the real <LoginPage />
component.
In src/App.js
, do NOT copy & paste the “...” pls
...
import LoginPage from "./components/LoginPage";
...
renderContent = () => {
if (!this.state.authed) {
return <LoginPage handleLoginSuccess={this.handleLoginSuccess} />;
}
...
};
...
// import logo from './logo.svg';
// import './App.css';
// function App() {
// return (
// <div className="App">
// <header className="App-header">
// <img src={logo} className="App-logo" alt="logo" />
// <p>
// Edit <code>src/App.js</code> and save to reload.
// </p>
// <a
// className="App-link"
// href="https://reactjs.org"
// target="_blank"
// rel="noopener noreferrer"
// >
// Learn React
// </a>
// </header>
// </div>
// );
// }
// export default App;
import { Layout, Dropdown, Menu, Button } from "antd";
import { UserOutlined } from "@ant-design/icons";
import React from "react";
import LoginPage from "./components/LoginPage";
const { Header, Content } = Layout;
class App extends React.Component {
state = {
authed: false,
asHost: false,
};
componentDidMount() {
const authToken = localStorage.getItem("authToken");
const asHost = localStorage.getItem("asHost") === "true";
this.setState({
authed: authToken !== null,
asHost,
});
}
handleLoginSuccess = (token, asHost) => {
localStorage.setItem("authToken", token);
localStorage.setItem("asHost", asHost);
this.setState({
authed: true,
asHost,
});
};
handleLogOut = () => {
localStorage.removeItem("authToken");
localStorage.removeItem("asHost");
this.setState({
authed: false,
});
};
renderContent = () => {
if (!this.state.authed) {
// return <div>login page</div>;
return <LoginPage handleLoginSuccess={this.handleLoginSuccess} />;
}
if (this.state.asHost) {
return <div>host home page</div>;
}
return <div>guest home page</div>;
};
userMenu = (
<Menu>
<Menu.Item key="logout" onClick={this.handleLogOut}>
Log Out
</Menu.Item>
</Menu>
);
render() {
return (
<Layout style={{ height: "100vh" }}>
<Header style={{ display: "flex", justifyContent: "space-between" }}>
<div style={{ fontSize: 16, fontWeight: 600, color: "white" }}>
Stays Booking
</div>
{this.state.authed && (
<div>
<Dropdown trigger="click" overlay={this.userMenu}>
<Button icon={<UserOutlined />} shape="circle" />
</Dropdown>
</div>
)}
</Header>
<Content
style={{ height: "calc(100% - 64px)", margin: 20, overflow: "auto" }}
>
{this.renderContent()}
</Content>
</Layout>
);
}
}
export default App;
跨域问题
服务器可能停止了 需要重启
ip地址会变