Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jeremy/eng 997b current upcoming #222

Merged
merged 24 commits into from
Mar 4, 2019

Conversation

jerminatorhits
Copy link
Contributor

Description

Why did you write this code?
display current and upcoming trips
port over the contact host modal to bootstrap
port over the cancelBooking alert/modal to bootstrap

How to Test

  • Visit '/work/trips'
  • Click 'upcoming' and 'current' to see respective bookings
  • Send message via 'Contact Host' to host successfully
  • Successfully cancel a booking using 'Cancel Booking'

Which devices did you test on?

  • Chrome on Mac
  • Chrome on PC
  • Firefox on Mac
  • Firefox on PC
  • Safari iPhone
  • Chrome Android

REVIEWERS:

Check against these principles:

High level

Does this code need to be written?
What are the alternatives?
Will this implementation become a support issue?
How much error margin does this solution have?

Code

Variables/Naming:

  • Would the variable type led to future edge cases?
  • Are the variable naming clear? Would the value contain something other than what the name describes.

Security

  • Can this be hacked or abused by the user?

Further Work

Will this have future work?

Learnings

Did you learn anything here you want to share with the team?

@jerminatorhits jerminatorhits changed the title Jeremy/eng 997b current upcoming WIP Jeremy/eng 997b current upcoming Mar 1, 2019
@jerminatorhits
Copy link
Contributor Author

Note: Using the same cards for all 4 tabs. Weird thing was that I was able to cancel a booking on the 'Cancelled/Rejected' tab.

Next PR will do the following:

  • remove 'cancel booking' button
  • add the red status text for cancelled/reject cards
  • fix photo image to fit different screens and card sizes, without quality loss.

@jerminatorhits jerminatorhits mentioned this pull request Mar 1, 2019
9 tasks
<ModalHeader>Cancel Booking</ModalHeader>
<ModalBody>
<h6>Are you sure you want to cancel this booking?</h6>
{booking && <h6>{`Booking: ${booking.id}`}</h6>}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks equivalent to:

<h6>Booking: {booking.id}</h6>

(booking is non-optional in Props so the check has been handled at compile-time, and there's some extra syntax around the templated part)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oo makes sense. thanks!

</ModalBody>
<ModalFooter>
<Button color="secondary" disabled={isSubmitting} onClick={() => handleModalAction()}>Back</Button>{' '}
<Button color="danger" disabled={isSubmitting} onClick={() => handleCancelBooking()}>Yes, Cancel Booking</Button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both onClick handlers are no-argument functions so you should be able to pass them in directly:

onClick={handleModalAction}
onClick={handleCancelBooking}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brilliant. will keep in mind in the future!

);

function handleCancelBooking() {
if (!booking) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is also unnecessary (handled at compile-time by enforcing Props interface)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 the node backend in me must've gotten nervous =x

interface Props {
booking: Booking;
cancelBooking: (booking: Booking) => Promise<Booking>;
handleModalAction: () => void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with React naming conventions, I'd expect this to be onModalAction at the interface level and handleModalAction at the implementation level, for usage like:

<CancelBookingModal onModalAction={handleModalAction} etc... />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was bugging me in the back of my head. I'll try to remember or refer back to this in the future. tyty!

message: Yup.string().required('Please fill out the message field.'),
});

function ContactHostForm({ booking, contactUser, handleModalAction }: Props) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yay, this will come in handy for the Contact Host button on the listing page

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

interface Props {
contactUser: (input: ContactUserInput) => Promise<EmailResponse>;
booking: Booking;
handleModalAction: () => void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, I'd expect this to be named onModalAction

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 done

<CardTitle className="h5 font-weight-normal mb-3">{booking.listing.title}</CardTitle>
<CardSubtitle className="small mb-3">
{addressLine1 && formatAddress(addressLine1, addressLine2, city, state, country, postalCode)}
{!addressLine1 && formatGeolocationAddress({ lat, lng, city, country })}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small change, but I'd do this as:

{addressLine1 ? formatAddress(...) : formatGeolocationAddress(...)}

Rationale is maintainability; the logic for the two checks is necessarily complementary (we want exactly one of these formatted outputs to be displayed) but separating them allows them to diverge (e.g if we change addressLine1 to (addressLine1 || addressLine2) on one line but not the next)

Also, I may be misremembering, but I think we added a fullAddress field to listings on the backend that handles this formatting ahead of time, so you might just be able to say booking.listing.fullAddress here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, backend defines fullAddress as:

  fullAddress: {
    type: DataTypes.VIRTUAL,
    get: function () {
      const { addressLine1, addressLine2, city, state, country, postalCode, lat, lng } = this;
      return addressLine1 ?
        formatAddress(addressLine1, addressLine2, city, state, country, postalCode) :
        formatGeolocationAddress({ lat, lng, city, country });
    }
  }

May need to update GraphQL queries to expose it tho; in the GraphQL booking end point there is a Listing type defined which does not include this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting. definitely on board with the maintainability factor (leaves smaller margin of error as stated)

As for the fullAddress, I think some cards should only show city, state, country, etc. (omitting street address since it shouldn't be shown to unapproved bookings). Would it be better practice to handle that in the backend?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually lemme smoke test this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the fullAddress, I think some cards should only show city, state, country, etc. (omitting street address since it shouldn't be shown to unapproved bookings). Would it be better practice to handle that in the backend?

Ah, you're right; fullAddress (as currently defined) should only be exposed for approved bookings. Sounds like we want something like a displayAddress that takes into account the privileges of the user doing the viewing? In any case, that's getting out of scope for this issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh makes sense. Will put in the fix for a ternary at the very least

@tc
Copy link
Contributor

tc commented Mar 2, 2019

The Contact Host should be an a tag or button so it gets a natural mouse cursor
Same with Cancel Trip.
right now, it's a text selection.

</Row>
<Row>
<a href='/work'>
<Button>Book a Home Today!</Button>
Copy link
Contributor

@tc tc Mar 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can remove the button tag and this can be <a className="btn"> so the cursor is correctly registered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@jerminatorhits
Copy link
Contributor Author

seems like <a> tag only provides the pointer when an href is declared (which won't work for the modal).

Button has a lot of intrinsic padding as well
image

Made a custom css class after doing some research on a pretty back-and-forth discussion: twbs/bootstrap#23709

.c-pointer {
 cursor: pointer;
}

@tc
Copy link
Contributor

tc commented Mar 3, 2019

@jerminatorhits curious, could you add href="#" to the a tag? I think the javascript does a preventDefault() to overridden the call.

<Row className="align-items-center">
<Col
xs="4"
onClick={() => handleModalAction(ModalType.CONTACT_HOST)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this be onClick={handleOpenContactHostModal} and the method call handleModalAction(ModalType.CONTACT_HOST) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could do. since there's also a CANCEL_BOOKING modal, that would require a handleOpenCancelBookingModal to be passed into this component as well. If it's conventionally better to use specific handle names, I'm all for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think using a method can ensure better enforcement vs a parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see. so the component doesn't have to know about the enum. will change

@jerminatorhits
Copy link
Contributor Author

@tc put an href="#" on the a tag and it has the pointer but goes to home page.

@tc
Copy link
Contributor

tc commented Mar 4, 2019

@tc put an href="#" on the a tag and it has the pointer but goes to home page.
does the onClick listener have a e.preventDefault or e.stopPropagation ?

@jerminatorhits
Copy link
Contributor Author

@tc <a href="#" onClick={(event: React.MouseEvent<HTMLElement>) => event.preventDefault()}>

includes the pointer and opens the modal. Interesting!

@jerminatorhits jerminatorhits merged commit 7f994de into master Mar 4, 2019
@jerminatorhits jerminatorhits deleted the jeremy/ENG-997b-current-upcoming branch March 4, 2019 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants