Skip to content

Commit

Permalink
Merge pull request #52 from HadikaMalik/PedroRicciardi/Component/Cust…
Browse files Browse the repository at this point in the history
…omerProfile

Pedro Ricciardi/Component/Customer Profile
  • Loading branch information
HadikaMalik authored Mar 14, 2024
2 parents f2ecce6 + 3374c6e commit d4ac17a
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 30 deletions.
57 changes: 39 additions & 18 deletions src/components/Booking/Booking.jsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,56 @@
import dayjs from "dayjs";
import { useState } from "react";

import CustomerProfile from "../CustomerProfile/CustomerProfile";

import "./Booking.scss";

const Booking = (props) => {
// prettier-ignore
const { title, firstName, surname, email, roomId, checkInDate, checkOutDate } = props.booking;
const { id, title, firstName, surname, email, roomId, checkInDate, checkOutDate } = props.booking;
const stayNights = dayjs(checkOutDate).diff(dayjs(checkInDate), "d");
const [selected, setSelected] = useState(false);
const [showProfile, setShowProfile] = useState(false);

const selectBookingHandle = () => {
setSelected(!selected);
}
showProfileHandle();
};

const showProfileHandle = () => {
setShowProfile(!showProfile);
};

return (
<tr
className={selected ? "booking-row booking-row-selected" : "booking-row"}
data-testid="booking-component"
onClick={selectBookingHandle}
>
<td className="customer-name">
{title} {firstName} {surname}
</td>
<td className="customer-email">{email}</td>
<td className="customer-room">{roomId}</td>
<td className="customer-checkin">{checkInDate}</td>
<td className="customer-checkout">{checkOutDate}</td>
<td className="customer-stay">
{stayNights} {stayNights > 1 ? "nights" : "night"}
</td>
</tr>
<>
<tr
className={
selected ? "booking-row booking-row-selected" : "booking-row"
}
data-testid="booking-component"
>
<td className="customer-name">
{title} {firstName} {surname}
</td>
<td className="customer-email">{email}</td>
<td className="customer-room">{roomId}</td>
<td className="customer-checkin">{checkInDate}</td>
<td className="customer-checkout">{checkOutDate}</td>
<td className="customer-stay">
{stayNights} {stayNights > 1 ? "nights" : "night"}
</td>
<td>
<button
data-testid="show-profile-button"
className="customer-show-profile-button"
onClick={selectBookingHandle}
>
Show profile
</button>
</td>
</tr>
{showProfile ? <CustomerProfile id={id} /> : null}
</>
);
};

Expand Down
8 changes: 4 additions & 4 deletions src/components/Booking/Booking.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { render, screen, fireEvent } from "@testing-library/react";
import Booking from "./Booking.jsx";
import FakeBookings from "../../data/fakeBookings.json";

console.log(FakeBookings);

describe("Booking Component", () => {
it("renders a booking component", () => {
const booking = FakeBookings[0];
Expand All @@ -15,18 +13,20 @@ describe("Booking Component", () => {

it("toggles selection when clicked", () => {
const booking = FakeBookings[0];

render(<Booking booking={booking} />);
const bookingComponent = screen.getByTestId("booking-component");
const showProfileButton = screen.getByTestId("show-profile-button");

// Check that the component does not have the selected class by default
expect(bookingComponent).not.toHaveClass("booking-row-selected");

// Simulate a click event to toggle selection
fireEvent.click(bookingComponent);
fireEvent.click(showProfileButton);
expect(bookingComponent).toHaveClass("booking-row-selected");

// Simulate a second click event to deselect
fireEvent.click(bookingComponent);
fireEvent.click(showProfileButton);
expect(bookingComponent).not.toHaveClass("booking-row-selected");
});
});
4 changes: 2 additions & 2 deletions src/components/Bookings/Bookings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const Bookings = () => {
return (
<main className="bookings">
<Search search={search} />
{<SearchResults bookings={bookings} />}
<SearchResults bookings={bookings} />
</main>
);
};

export default Bookings;
export default Bookings;
37 changes: 37 additions & 0 deletions src/components/CustomerProfile/CustomerProfile.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useState, useEffect } from "react";

import "./CustomerProfile.scss";

const CustomerProfile = ({ id }) => {
const [customerProfileData, setCustomerProfileData] = useState(null);

useEffect(() => {
fetch(`https://cyf-hotel-api.netlify.app/customers/${id}`)
.then((response) => response.json())
.then((data) => setCustomerProfileData(data))
.catch((error) =>
console.error("Error fetching customer profile:", error)
);
}, [id]);

if (!customerProfileData) {
return (
<tr data-testid="customer-profile" className="customer-row">
<td colSpan={2}>Loading...</td>
</tr>
);
}

return (
<tr data-testid="customer-profile" className="customer-row">
<td colSpan={2}>Phone: {customerProfileData.phoneNumber}</td>
<td colSpan={2} className={customerProfileData.vip ? `vip-customer` : ``}>
{customerProfileData.vip ? `VIP Customer` : `Regular Customer`}
</td>
<td>ID: {customerProfileData.id}</td>
<td colSpan={2}>More info</td>
</tr>
);
};

export default CustomerProfile;
42 changes: 42 additions & 0 deletions src/components/CustomerProfile/CustomerProfile.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
:root {
--customer-row-light: 25%;
--customer-row-saturation: 30%;
}

.hidden {
display: none;
}

.customer-row:nth-child(even) {
background-color: hsl(
246,
var(--customer-row-saturation),
var(--customer-row-light)
);
}

.customer-row:nth-child(odd) {
background-color: hsl(
236,
var(--customer-row-saturation),
var(--customer-row-light)
);
}

td {
text-align: center;
}

.vip-customer {
background-color: hsl(
176,
var(--customer-row-saturation),
var(--customer-row-light)
);
}

@media (prefers-color-scheme: light) {
:root {
--customer-row-light: 80%;
}
}
40 changes: 40 additions & 0 deletions src/components/CustomerProfile/CustomerProfile.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { describe, it, expect } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import Booking from "../Booking/Booking";
import FakeBookings from "../../data/fakeBookings.json";

describe("CustomerProfile Component", () => {
it("renders a booking component", () => {
const booking = FakeBookings[0];
render(<Booking booking={booking} />);
const bookingComponent = screen.getByTestId("booking-component");
expect(bookingComponent).toBeInTheDocument();
});

it("first page load should not render the CustomerProfile component", () => {
const booking = FakeBookings[0];

render(<Booking booking={booking} />);
const bookingComponent = screen.getByTestId("booking-component");
const CustomerProfileComponent = screen.queryByTestId("customer-profile");

expect(bookingComponent).toBeInTheDocument();

expect(CustomerProfileComponent).toBeNull();
});

it("clicking on the 'Show Profile' button should render the CustomerProfile component", () => {
const booking = FakeBookings[0];
render(<Booking booking={booking} />);

const bookingComponent = screen.getByTestId("booking-component");
const showProfileButton = screen.getByTestId("show-profile-button");

fireEvent.click(showProfileButton);

const CustomerProfileComponent = screen.getByTestId("customer-profile");

expect(bookingComponent).toBeInTheDocument();
expect(CustomerProfileComponent).toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions src/components/SearchResults/SearchResults.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const SearchResults = (props) => {
<th scope="col">Check in</th>
<th scope="col">Check out</th>
<th scope="col">Stay for</th>
<th scope="col">Profile</th>
</tr>
</thead>
<tbody>
Expand Down
14 changes: 8 additions & 6 deletions src/components/SearchResults/SearchResults.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,25 @@ describe("SearchResults Component", () => {
it("toggles the selection for each booking", () => {
render(<SearchResults bookings={FakeBookings} />);
const bookingComponents = screen.getAllByTestId("booking-component");
const showProfileButtons = screen.getAllByTestId("show-profile-button");

bookingComponents.forEach((booking) => {
fireEvent.click(booking);
bookingComponents.forEach((booking, index) => {
fireEvent.click(showProfileButtons[index]);
expect(booking).toHaveClass("booking-row-selected");
});
});

it("toggles off the selection for each booking", () => {
render(<SearchResults bookings={FakeBookings} />);
const bookingComponents = screen.getAllByTestId("booking-component");
const showProfileButtons = screen.getAllByTestId("show-profile-button");

bookingComponents.forEach((booking) => {
fireEvent.click(booking);
bookingComponents.forEach((booking, index) => {
fireEvent.click(showProfileButtons[index]);
});

bookingComponents.forEach((booking) => {
fireEvent.click(booking);
bookingComponents.forEach((booking, index) => {
fireEvent.click(showProfileButtons[index]);
expect(booking).not.toHaveClass("booking-row-selected");
});
});
Expand Down

0 comments on commit d4ac17a

Please sign in to comment.