14 StayBooking Client 4
14 StayBooking Client 4
All the follows happen in src/components/HostHomePage.js
Remove Stay Button (for those imports, copy and override all imports)
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 { deleteStay, getStaysByHost } from "../utils";
class RemoveStayButton extends React.Component {
state = {
loading: false,
};
handleRemoveStay = async () => {
const { stay, onRemoveSuccess } = this.props;
this.setState({
loading: true,
});
try {
await deleteStay(stay.id);
onRemoveSuccess();
} catch (error) {
message.error(error.message);
} finally {
this.setState({
loading: false,
});
}
};
render() {
return (
<Button
loading={this.state.loading}
onClick={this.handleRemoveStay}
danger={true}
shape="round"
type="primary"
>
Remove Stay
</Button>
);
}
}
In MyStays component
View Reservations Button
...
import { deleteStay, getReservationsByStay, getStaysByHost } from "../utils";
...
class ReservationList extends React.Component {
state = {
loading: false,
reservations: [],
};
componentDidMount() {
this.loadData();
}
loadData = async () => {
this.setState({
loading: true,
});
try {
const resp = await getReservationsByStay(this.props.stayId);
this.setState({
reservations: resp,
});
} catch (error) {
message.error(error.message);
} finally {
this.setState({
loading: false,
});
}
};
render() {
const { loading, reservations } = this.state;
return (
<List
loading={loading}
dataSource={reservations}
renderItem={(item) => (
<List.Item>
<List.Item.Meta
title={<Text>Guest Name: {item.guest.username}</Text>}
description={
<>
<Text>Checkin Date: {item.checkin_date}</Text>
<br />
<Text>Checkout Date: {item.checkout_date}</Text>
</>
}
/>
</List.Item>
)}
/>
);
}
}
class ViewReservationsButton extends React.Component {
state = {
modalVisible: false,
};
openModal = () => {
this.setState({
modalVisible: true,
});
};
handleCancel = () => {
this.setState({
modalVisible: false,
});
};
render() {
const { stay } = this.props;
const { modalVisible } = this.state;
const modalTitle = `Reservations of ${stay.name}`;
return (
<>
<Button onClick={this.openModal} shape="round">
View Reservations
</Button>
{modalVisible && (
<Modal
title={modalTitle}
centered={true}
visible={modalVisible}
closable={false}
footer={null}
onCancel={this.handleCancel}
destroyOnClose={true}
>
<ReservationList stayId={stay.id} />
</Modal>
)}
</>
);
}
}
class MyStays extends React.Component {
...
<Card
...
actions={[<ViewReservationsButton stay={item} />]}
...
>
...
}
Upload Stay
src/components/UploadStay.js
import React from "react";
import { Form, Input, InputNumber, Button, message } from "antd";
import { uploadStay } from "../utils";
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
class UploadStay extends React.Component {
state = {
loading: false,
};
fileInputRef = React.createRef();
handleSubmit = async (values) => {
const formData = new FormData();
const { files } = this.fileInputRef.current;
if (files.length > 5) {
message.error("You can at most upload 5 pictures.");
return;
}
for (let i = 0; i < files.length; i++) {
formData.append("images", files[i]);
}
formData.append("name", values.name);
formData.append("address", values.address);
formData.append("description", values.description);
formData.append("guest_number", values.guest_number);
this.setState({
loading: true,
});
try {
await uploadStay(formData);
message.success("upload successfully");
} catch (error) {
message.error(error.message);
} finally {
this.setState({
loading: false,
});
}
};
render() {
return (
<Form
{...layout}
name="nest-messages"
onFinish={this.handleSubmit}
style={{ maxWidth: 1000, margin: "auto" }}
>
<Form.Item name="name" label="Name" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name="address" label="Address" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item
name="description"
label="Description"
rules={[{ required: true }]}
>
<Input.TextArea autoSize={{ minRows: 2, maxRows: 6 }} />
</Form.Item>
<Form.Item
name="guest_number"
label="Guest Number"
rules={[{ required: true, type: "number", min: 1 }]}
>
<InputNumber />
</Form.Item>
<Form.Item name="picture" label="Picture" rules={[{ required: true }]}>
<input
type="file"
accept="image/png, image/jpeg"
ref={this.fileInputRef}
multiple={true}
/>
</Form.Item>
<Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
<Button type="primary" htmlType="submit" loading={this.state.loading}>
Submit
</Button>
</Form.Item>
</Form>
);
}
}
export default UploadStay;
Don’t forget to replace the placeholder here (
...
import UploadStay from "./UploadStay";
...
class HostHomePage extends React.Component {
render() {
return (
<Tabs defaultActiveKey="1" destroyInactiveTabPane={true}>
<TabPane tab="My Stays" key="1">
<MyStays />
</TabPane>
<TabPane tab="Upload Stay" key="2">
<UploadStay />
</TabPane>
</Tabs>
);
}
}