-
Notifications
You must be signed in to change notification settings - Fork 3
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
Conversation
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:
|
<ModalHeader>Cancel Booking</ModalHeader> | ||
<ModalBody> | ||
<h6>Are you sure you want to cancel this booking?</h6> | ||
{booking && <h6>{`Booking: ${booking.id}`}</h6>} |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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}
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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... />
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 })} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
The Contact Host should be an |
src/pages/trips/Trips.tsx
Outdated
</Row> | ||
<Row> | ||
<a href='/work'> | ||
<Button>Book a Home Today!</Button> |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
seems like
Made a custom css class after doing some research on a pretty back-and-forth discussion: twbs/bootstrap#23709
|
@jerminatorhits curious, could you add |
<Row className="align-items-center"> | ||
<Col | ||
xs="4" | ||
onClick={() => handleModalAction(ModalType.CONTACT_HOST)} |
There was a problem hiding this comment.
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)
?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
@tc put an |
|
@tc includes the pointer and opens the modal. Interesting! |
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
Which devices did you test on?
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
Does the code follow industry standards?
JS: https://github.com/airbnb/javascript
React: https://github.com/airbnb/javascript/tree/master/react
https://github.com/vasanthk/react-bits
Documentation headers: http://usejsdoc.org/index.html
Is there duplicated code? Can it be refactored into a shared method?
Is the code consistent with our project?
Are there unit tests? Do they test the states?
Is the person refactoring another developer's code? If possible, did the original developer approve?
Variables/Naming:
Security
Further Work
Will this have future work?
Learnings
Did you learn anything here you want to share with the team?