Skip to content

Commit

Permalink
finished adding createbooking modal
Browse files Browse the repository at this point in the history
  • Loading branch information
jalajcodes committed Oct 5, 2020
1 parent 12144fd commit 30b99f0
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 49 deletions.
15 changes: 9 additions & 6 deletions src/lib/components/ListingCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { Card, Typography, Modal } from 'antd';
import { UserOutlined } from '@ant-design/icons';
import { UserOutlined, ArrowRightOutlined } from '@ant-design/icons';
import { Link } from 'react-router-dom';
import { iconColor, formatListingPrice, displaySuccessNotification } from '../../utils';
import { ListingCardActions } from './components';
Expand Down Expand Up @@ -77,16 +77,19 @@ export const ListingCard = ({ listing, viewerIsUser, refetch }: Props) => {
</Link>
{listingCardActionsElement}
<Modal
title="Confirm Delete"
okText="Delete"
okButtonProps={{ style: { background: 'red', color: 'white' } }}
title={'Are you sure you want to delete this listing?'}
okText="Yes"
cancelText="No"
// okButtonProps={{ style: { background: 'red', color: 'white' } }}
// cancelButtonProps={{ style: { background: '#00ff00d4', color: 'white' } }}
visible={showModal}
confirmLoading={loading}
onCancel={handleCancel}
onOk={handleDelete}>
<p>Are you sure you want to delete this listing? </p>
<p style={{ textTransform: 'uppercase' }}>
<strong>{title}</strong>
<Text strong>
<ArrowRightOutlined size={24} style={{ color: iconColor }} /> {title}
</Text>
</p>
</Modal>
</>
Expand Down
7 changes: 7 additions & 0 deletions src/lib/graphql/globalTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ export enum ListingsFilter {
PRICE_LOW_TO_HIGH = "PRICE_LOW_TO_HIGH",
}

export interface CreateBookingInput {
id: string;
source: string;
checkIn: string;
checkOut: string;
}

export interface DeleteListingInput {
id: string;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/lib/graphql/mutations/CreateBooking/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { gql } from '@apollo/client';
export const CREATE_BOOKING = gql`
mutation CreateBooking($input: CreateBookingInput!) {
createBooking(input: $input) {
id
}
}
`;
5 changes: 3 additions & 2 deletions src/lib/graphql/mutations/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './LogIn';
export * from './LogOut';
export * from './ConnectStripe';
export * from './CreateBooking';
export * from './DeleteListing';
export * from './DisconnectStripe';
export * from './HostListing';
export * from './LogIn';
export * from './LogOut';
32 changes: 16 additions & 16 deletions src/lib/graphql/queries/EditListing/__generated__/EditListing.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 6 additions & 9 deletions src/sections/AppHeader/components/MenuItems/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useState } from 'react';
import React from 'react';
import { useHistory } from 'react-router-dom';
import { Button, Menu, Avatar } from 'antd';
import { HomeOutlined, UserOutlined, LogoutOutlined } from '@ant-design/icons';
import { Link, Redirect } from 'react-router-dom';
import { Link } from 'react-router-dom';
import useViewerState from '../../../../lib/context/useViewerState';
import { useMutation } from '@apollo/client';
import { LOG_OUT } from '../../../../lib/graphql/mutations';
Expand All @@ -16,15 +17,15 @@ const { SubMenu, Item } = Menu;
// }

export const MenuItems = () => {
const history = useHistory();
const { viewer, setViewer } = useViewerState();
const [c, d] = useState(false);
const [logOut] = useMutation<LogOutData>(LOG_OUT, {
onCompleted: (data) => {
if (data && data.logout) {
setViewer(data.logout);
sessionStorage.removeItem('token');
displaySuccessNotification("You've been Successfully Logged Out.");
d(true);
displaySuccessNotification('Successfully Logged Out.');
history.push('/');
}
},
onError: () => {
Expand All @@ -36,10 +37,6 @@ export const MenuItems = () => {
logOut();
};

if (c) {
return <Redirect to="/" />;
}

const subMenu =
viewer.id && viewer.avatar ? (
<SubMenu title={<Avatar src={viewer.avatar} />}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,53 @@
import React from 'react';
import { Button, Divider, Modal, Typography } from 'antd';
import { Button, Divider, message, Modal, Typography } from 'antd';
import { KeyOutlined } from '@ant-design/icons';
import moment, { Moment } from 'moment';
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
import { formatListingPrice } from '../../../../lib/utils';
import { formatListingPrice, displayErrorMessage, displaySuccessNotification } from '../../../../lib/utils';
import { useMutation } from '@apollo/client';
import { CREATE_BOOKING } from '../../../../lib/graphql/mutations/CreateBooking';
import {
CreateBooking as CreateBookingData,
CreateBookingVariables,
} from '../../../../lib/graphql/mutations/CreateBooking/__generated__/CreateBooking';

interface Props {
id: string;
modalVisible: boolean;
setModalVisible: (modalVisible: boolean) => void;
checkInDate: Moment;
checkOutDate: Moment;
price: number;
setModalVisible: (modalVisible: boolean) => void;
clearBookingData: () => void;
refetchListing: () => Promise<void>;
}

const { Paragraph, Title, Text } = Typography;

export const ListingCreateBookingModal = ({
id,
checkInDate,
checkOutDate,
price,
modalVisible,
setModalVisible,
clearBookingData,
refetchListing,
}: Props) => {
const [createBooking, { loading }] = useMutation<CreateBookingData, CreateBookingVariables>(CREATE_BOOKING, {
onCompleted: () => {
clearBookingData();
displaySuccessNotification(
"You've successfully booked the listing!",
'Booking history can always be found in your Profile.'
);
refetchListing();
},
onError: () => {
displayErrorMessage("Sorry! We weren't able to book the listing. Please try again later!");
},
});

const daysBooked = checkOutDate.diff(checkInDate, 'days') + 1;
const listingPrice = price * daysBooked;

Expand All @@ -35,8 +61,22 @@ export const ListingCreateBookingModal = ({

if (!cardElement) return;

const { token: stripeToken } = await stripe.createToken(cardElement);
console.log(stripeToken);
const { token: stripeToken, error } = await stripe.createToken(cardElement);

if (stripeToken) {
createBooking({
variables: {
input: {
id,
source: stripeToken.id,
checkIn: moment(checkInDate).format('YYYY-MM-DD'),
checkOut: moment(checkInDate).format('YYYY-MM-DD'),
},
},
});
} else {
displayErrorMessage(error && error.message ? error.message : 'Unable to Book the Listing. Try again later.');
}
};

return (
Expand Down Expand Up @@ -81,7 +121,12 @@ export const ListingCreateBookingModal = ({
className="listing-booking-modal__stripe-card"
/>

<Button size="large" type="primary" className="listing-booking-modal__cta" onClick={handleClick}>
<Button
loading={loading}
size="large"
type="primary"
className="listing-booking-modal__cta"
onClick={handleClick}>
Book
</Button>
</div>
Expand Down
17 changes: 15 additions & 2 deletions src/sections/Listing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,24 @@ export const Listing = () => {
const [checkOutDate, setCheckOutDate] = useState<Moment | null>(null);
const [modalVisible, setModalVisible] = useState(false);

const { data, loading, error } = useQuery<ListingData, ListingVariables>(LISTING, {
const { data, loading, error, refetch } = useQuery<ListingData, ListingVariables>(LISTING, {
variables: {
id,
bookingsPage,
limit: PAGE_LIMIT,
},
});

const refetchListing = async () => {
await refetch();
};

const clearBookingData = () => {
setCheckOutDate(null);
setCheckInDate(null);
setModalVisible(false);
};

if (loading) {
return (
<Content className="listings">
Expand Down Expand Up @@ -58,7 +68,7 @@ export const Listing = () => {
{/* Listing Details */}
{listing ? <ListingDetails listing={listing} /> : null}

{/* Bookings for above listing */}
{/* Bookings for above listing, only visible to the owner */}
{listingBookings ? (
<ListingBookings
limit={PAGE_LIMIT}
Expand Down Expand Up @@ -86,6 +96,9 @@ export const Listing = () => {
</Row>
{listing && checkInDate && checkOutDate && (
<ListingCreateBookingModal
id={listing.id}
clearBookingData={clearBookingData}
refetchListing={refetchListing}
price={listing.price}
modalVisible={modalVisible}
checkInDate={checkInDate}
Expand Down
9 changes: 2 additions & 7 deletions src/sections/User/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,9 @@ export const User = () => {
);
}



return (
<Layout hasSider>
<Sider
breakpoint="lg"
width={250}
className="user-sider">
<Sider breakpoint="lg" width={250} className="user-sider">
<Menu
mode="inline"
// this is just a hack to add correct stying based on the path
Expand All @@ -110,7 +105,7 @@ export const User = () => {
}>
<div className="user-sider__menuitem-avatar">
{/* <Avatar size={100} style={{ backgroundColor: iconColor }} icon={<UserOutlined />} /> */}
<Avatar size={100} src={user?.avatar} />
<Avatar size="large" src={user?.avatar} />
</div>
<Menu.Item key="1" icon={<UserOutlined />}>
<NavLink exact activeClassName="ant-menu-item-selected ant-menu-item-active" to={`/user/${idUrlParam}`}>
Expand Down
2 changes: 1 addition & 1 deletion src/styles/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@
}
.user {
background-color: #fff;
padding-left: 50px;
padding: 0 50px;
}
// @media (max-width: 75em) {
// .user {
Expand Down

0 comments on commit 30b99f0

Please sign in to comment.