13 StayBooking Client 3
13 StayBooking Client 3
We will build the home page host users first so we can upload “stays” for guests to book.
Host Home Page
Create src/components/HostHomePage.js
import React from "react";
import { Tabs } from "antd";
const { TabPane } = Tabs;
class HostHomePage extends React.Component {
render() {
return (
<Tabs defaultActiveKey="1" destroyInactiveTabPane={true}>
<TabPane tab="My Stays" key="1">
<div>My Stays Content</div>
</TabPane>
<TabPane tab="Upload Stay" key="2">
<div>Upload Stays</div>
</TabPane>
</Tabs>
);
}
}
export default HostHomePage;
In src/App.js, let’s place this component where it belongs, don’t copy & paste the “...”
...
import HostHomePage from "./components/HostHomePage";
...
renderContent = () => {
...
if (this.state.asHost) {
return <HostHomePage />;
}
...
};
...
My Stays Component
In src/components/HostHomePage.js
- Add component “StayDetailsInfoButton” to this file
- Add component “MyStays” to this file
- Copy paste the whole “imports” area
import { message, Tabs, List, Card, Image, Carousel } from "antd";
import { LeftCircleFilled, RightCircleFilled } from "@ant-design/icons";
import Text from "antd/lib/typography/Text";
import React from "react";
import { getStaysByHost } from "../utils";
...
...
export class StayDetailInfoButton extends React.Component {
render() {
return <></>;
}
}
...
class MyStays extends React.Component {
state = {
loading: false,
data: [],
};
componentDidMount() {
this.loadData();
}
loadData = async () => {
this.setState({
loading: true,
});
try {
const resp = await getStaysByHost();
this.setState({
data: resp,
});
} catch (error) {
message.error(error.message);
} finally {
this.setState({
loading: false,
});
}
};
render() {
return (
<List
loading={this.state.loading}
grid={{
gutter: 16,
xs: 1,
sm: 3,
md: 3,
lg: 3,
xl: 4,
xxl: 4,
}}
dataSource={this.state.data}
renderItem={(item) => (
<List.Item>
<Card
key={item.id}
title={
<div style={{ display: "flex", alignItems: "center" }}>
<Text ellipsis={true} style={{ maxWidth: 150 }}>
{item.name}
</Text>
<StayDetailInfoButton stay={item} />
</div>
}
actions={[]}
extra={null}
>
{
<Carousel
dots={false}
arrows={true}
prevArrow={<LeftCircleFilled />}
nextArrow={<RightCircleFilled />}
>
{item.images.map((image, index) => (
<div key={index}>
<Image src={image.url} width="100%" />
</div>
))}
</Carousel>
}
</Card>
</List.Item>
)}
/>
);
}
}
...
import { message, Tabs, List, Card, Image, Carousel } from "antd";
import { LeftCircleFilled, RightCircleFilled } from "@ant-design/icons";
import Text from "antd/lib/typography/Text";
import React from "react";
import { getStaysByHost } from "../utils";
const { TabPane } = Tabs;
class HostHomePage extends React.Component {
render() {
return (
<Tabs defaultActiveKey="1" destroyInactiveTabPane={true}>
<TabPane tab="My Stays" key="1">
<div>My Stays Content</div>
</TabPane>
<TabPane tab="Upload Stay" key="2">
<div>Upload Stays</div>
</TabPane>
</Tabs>
);
}
}
export class StayDetailInfoButton extends React.Component {
render() {
return <></>;
}
}
class MyStays extends React.Component {
state = {
loading: false,
data: [],
};
componentDidMount() {
this.loadData();
}
loadData = async () => {
this.setState({
loading: true,
});
try {
const resp = await getStaysByHost();
this.setState({
data: resp,
});
} catch (error) {
message.error(error.message);
} finally {
this.setState({
loading: false,
});
}
};
render() {
return (
<List
loading={this.state.loading}
grid={{
gutter: 16,
xs: 1,
sm: 3,
md: 3,
lg: 3,
xl: 4,
xxl: 4,
}}
dataSource={this.state.data}
renderItem={(item) => (
<List.Item>
<Card
key={item.id}
title={
<div style={{ display: "flex", alignItems: "center" }}>
<Text ellipsis={true} style={{ maxWidth: 150 }}>
{item.name}
</Text>
<StayDetailInfoButton stay={item} />
</div>
}
actions={[]}
extra={null}
>
{
<Carousel
dots={false}
arrows={true}
prevArrow={<LeftCircleFilled />}
nextArrow={<RightCircleFilled />}
>
{item.images.map((image, index) => (
<div key={index}>
<Image src={image.url} width="100%" />
</div>
))}
</Carousel>
}
</Card>
</List.Item>
)}
/>
);
}
}
export default HostHomePage;
In HostHomePage.js, use the MyStays component here
...
class HostHomePage extends React.Component {
render() {
return (
<Tabs defaultActiveKey="1" destroyInactiveTabPane={true}>
<TabPane tab="My Stays" key="1">
<MyStays />
</TabPane>
...
In src/index.css add the lines as follows
.ant-carousel .slick-prev,
.ant-carousel .slick-next,
.ant-carousel .slick-prev:hover,
.ant-carousel .slick-next:hover {
font-size: inherit;
color: currentColor;
}
Stay Detail Info Button
import {
message,
Tabs,
List,
Card,
Image,
Carousel,
Button,
Tooltip,
Space,
Modal,
} from "antd";
import {
LeftCircleFilled,
RightCircleFilled,
InfoCircleOutlined,
} from "@ant-design/icons";
import Text from "antd/lib/typography/Text";
import React from "react";
import { getStaysByHost } from "../utils";
...
export class StayDetailInfoButton extends React.Component {
state = {
modalVisible: false,
};
openModal = () => {
this.setState({
modalVisible: true,
});
};
handleCancel = () => {
this.setState({
modalVisible: false,
});
};
render() {
const { stay } = this.props;
const { name, description, address, guest_number } = stay;
const { modalVisible } = this.state;
return (
<>
<Tooltip title="View Stay Details">
<Button
onClick={this.openModal}
style={{ border: "none" }}
size="large"
icon={<InfoCircleOutlined />}
/>
</Tooltip>
{modalVisible && (
<Modal
title={name}
centered={true}
visible={modalVisible}
closable={false}
footer={null}
onCancel={this.handleCancel}
>
<Space direction="vertical">
<Text strong={true}>Description</Text>
<Text type="secondary">{description}</Text>
<Text strong={true}>Address</Text>
<Text type="secondary">{address}</Text>
<Text strong={true}>Guest Number</Text>
<Text type="secondary">{guest_number}</Text>
</Space>
</Modal>
)}
</>
);
}
}