- {reviewData.bedrooms > 0 && (
+ {review.bedrooms > 0 && (
- {reviewData.bedrooms} {reviewData.bedrooms === 1 ? 'Bedroom' : 'Bedrooms'}
+ {review.bedrooms} {review.bedrooms === 1 ? 'Bedroom' : 'Bedrooms'}
)}
- {reviewData.price > 0 && (
+ {review.price > 0 && (
{' '}
- {getPriceRange(reviewData.price) || 0}
+ {getPriceRange(review.price) || 0}
)}
@@ -317,7 +323,7 @@ const ReviewComponent = ({
-
+
{formattedDate}
- {user && reviewData.userId && user.uid === reviewData.userId && (
+ {user && review.userId && user.uid === review.userId && (
openReviewModal()}>
@@ -350,7 +356,7 @@ const ReviewComponent = ({
-
+
@@ -362,19 +368,19 @@ const ReviewComponent = ({
- {expandedText ? reviewData.reviewText : reviewData.reviewText.substring(0, 500)}
- {!expandedText && reviewData.reviewText.length > 500 && '...'}
- {reviewData.reviewText.length > 500 ? (
+ {expandedText ? review.reviewText : review.reviewText.substring(0, 500)}
+ {!expandedText && review.reviewText.length > 500 && '...'}
+ {review.reviewText.length > 500 ? (
) : null}
- {reviewData.photos.length > 0 && (
+ {review.photos.length > 0 && (
- {reviewData.photos.map((photo) => {
+ {review.photos.map((photo) => {
return (
-
From 783b045c817c8920b398473b3991c7691d29940f Mon Sep 17 00:00:00 2001
From: Kea-Roy Ong <146872846+kea-roy@users.noreply.github.com>
Date: Thu, 7 Nov 2024 22:34:33 -0500
Subject: [PATCH 04/10] fetch helpful status on open for apartment
---
frontend/src/pages/ApartmentPage.tsx | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/frontend/src/pages/ApartmentPage.tsx b/frontend/src/pages/ApartmentPage.tsx
index 02eab58a..aeba454f 100644
--- a/frontend/src/pages/ApartmentPage.tsx
+++ b/frontend/src/pages/ApartmentPage.tsx
@@ -248,6 +248,32 @@ const ApartmentPage = ({ user, setUser }: Props): ReactElement => {
return subscribeLikes(setLikedReviews);
}, []);
+ // Fetch the reviews that the user has liked and set the liked reviews and like statuses.
+ useEffect(() => {
+ getUser(true).then((user) => {
+ if (user) {
+ user.getIdToken(true).then((token) => {
+ get(
+ `/api/review/like/${user.uid}`,
+ {
+ callback: (reviews) => {
+ const likedReviewsMap: Likes = {};
+ const likeStatusesMap: Likes = {};
+ reviews.forEach((review) => {
+ likedReviewsMap[review.id] = true;
+ likeStatusesMap[review.id] = false;
+ });
+ setLikedReviews(likedReviewsMap);
+ setLikeStatuses(likeStatusesMap);
+ },
+ },
+ createAuthHeaders(token)
+ );
+ });
+ }
+ });
+ }, []);
+
useEffect(() => {
get(`/api/buildings/all/${apt?.landlordId}`, {
callback: setOtherproperties,
From 8d73914cca22a4fc4a0ea5a8dac8f2bf6e4d5d00 Mon Sep 17 00:00:00 2001
From: Kea-Roy Ong <146872846+kea-roy@users.noreply.github.com>
Date: Thu, 7 Nov 2024 22:35:52 -0500
Subject: [PATCH 05/10] update bookmarks page to match new api request.
- adds query term for APPROVED
- delete from the list locally when it is disliked
---
frontend/src/pages/BookmarksPage.tsx | 31 ++++++++++++++--------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/frontend/src/pages/BookmarksPage.tsx b/frontend/src/pages/BookmarksPage.tsx
index 56407436..86408678 100644
--- a/frontend/src/pages/BookmarksPage.tsx
+++ b/frontend/src/pages/BookmarksPage.tsx
@@ -120,17 +120,15 @@ const BookmarksPage = ({ user, setUser }: Props): ReactElement => {
// Fetch helpful reviews data when the component mounts or when user changes or when toggle changes
useEffect(() => {
- const fetchLikedReviews = async () => {
- if (user) {
- const token = await user.getIdToken(true);
+ if (user) {
+ user.getIdToken(true).then((token) => {
get(
- `/api/review/like/${user.uid}`,
+ `/api/review/like/${user.uid}?status=APPROVED`,
{
callback: setHelpfulReviewsData,
},
createAuthHeaders(token)
);
-
// this is here so we can get the token when it's fetched and not cause an unauthorized error
get(
savedAPI,
@@ -141,9 +139,8 @@ const BookmarksPage = ({ user, setUser }: Props): ReactElement => {
},
createAuthHeaders(token)
);
- }
- };
- fetchLikedReviews();
+ });
+ }
}, [user, toggle, savedAPI, sortAptsBy]);
// Define the type of the properties used for sorting reviews
@@ -184,13 +181,17 @@ const BookmarksPage = ({ user, setUser }: Props): ReactElement => {
const token = await user.getIdToken(true);
const endpoint = dislike ? '/api/remove-like' : '/api/add-like';
await axios.post(endpoint, { reviewId }, createAuthHeaders(token));
- setHelpfulReviewsData((reviews) =>
- reviews.map((review) =>
- review.id === reviewId
- ? { ...review, likes: (review.likes || defaultLikes) + offsetLikes }
- : review
- )
- );
+ if (dislike) {
+ setHelpfulReviewsData((reviews) => reviews.filter((review) => review.id !== reviewId));
+ } else {
+ setHelpfulReviewsData((reviews) =>
+ reviews.map((review) =>
+ review.id === reviewId
+ ? { ...review, likes: (review.likes || defaultLikes) + offsetLikes }
+ : review
+ )
+ );
+ }
} catch (err) {
throw new Error('Error with liking review');
}
From 5b5a5d6502ca7cf1f97c627d194b0316bb1ab86d Mon Sep 17 00:00:00 2001
From: Kea-Roy Ong <146872846+kea-roy@users.noreply.github.com>
Date: Thu, 7 Nov 2024 22:36:57 -0500
Subject: [PATCH 06/10] update landlord page to fetch helpful status
---
frontend/src/pages/LandlordPage.tsx | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/frontend/src/pages/LandlordPage.tsx b/frontend/src/pages/LandlordPage.tsx
index 54716f12..42b82be4 100644
--- a/frontend/src/pages/LandlordPage.tsx
+++ b/frontend/src/pages/LandlordPage.tsx
@@ -178,6 +178,32 @@ const LandlordPage = ({ user, setUser }: Props): ReactElement => {
return subscribeLikes(setLikedReviews);
}, []);
+ // Fetch the reviews that the user has liked and set the liked reviews and like statuses.
+ useEffect(() => {
+ getUser(true).then((user) => {
+ if (user) {
+ user.getIdToken(true).then((token) => {
+ get(
+ `/api/review/like/${user.uid}`,
+ {
+ callback: (reviews) => {
+ const likedReviewsMap: Likes = {};
+ const likeStatusesMap: Likes = {};
+ reviews.forEach((review) => {
+ likedReviewsMap[review.id] = true;
+ likeStatusesMap[review.id] = false;
+ });
+ setLikedReviews(likedReviewsMap);
+ setLikeStatuses(likeStatusesMap);
+ },
+ },
+ createAuthHeaders(token)
+ );
+ });
+ }
+ });
+ }, []);
+
useEffect(() => {
const checkIfSaved = async () => {
try {
From 7849c0605d4413120e677bcdf6319886049d1dba Mon Sep 17 00:00:00 2001
From: Kea-Roy Ong <146872846+kea-roy@users.noreply.github.com>
Date: Thu, 7 Nov 2024 22:38:19 -0500
Subject: [PATCH 07/10] update profile page to retreve helpful status
- update pending reviews locally when like changes
---
frontend/src/pages/ProfilePage.tsx | 40 ++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/frontend/src/pages/ProfilePage.tsx b/frontend/src/pages/ProfilePage.tsx
index 7260f48e..09ef591a 100644
--- a/frontend/src/pages/ProfilePage.tsx
+++ b/frontend/src/pages/ProfilePage.tsx
@@ -181,6 +181,32 @@ const ProfilePage = ({ user, setUser }: Props): ReactElement => {
});
}, [user?.uid, toggle]);
+ // Fetch the reviews that the user has liked and set the liked reviews and like statuses.
+ useEffect(() => {
+ getUser(true).then((user) => {
+ if (user) {
+ user.getIdToken(true).then((token) => {
+ get(
+ `/api/review/like/${user.uid}`,
+ {
+ callback: (reviews) => {
+ const likedReviewsMap: Likes = {};
+ const likeStatusesMap: Likes = {};
+ reviews.forEach((review) => {
+ likedReviewsMap[review.id] = true;
+ likeStatusesMap[review.id] = false;
+ });
+ setLikedReviews(likedReviewsMap);
+ setLikeStatuses(likeStatusesMap);
+ },
+ },
+ createAuthHeaders(token)
+ );
+ });
+ }
+ });
+ }, []);
+
const likeHelper = (dislike = false) => {
return async (reviewId: string) => {
setLikeStatuses((reviews) => ({ ...reviews, [reviewId]: true }));
@@ -198,7 +224,16 @@ const ProfilePage = ({ user, setUser }: Props): ReactElement => {
const token = await user.getIdToken(true);
const endpoint = dislike ? '/api/remove-like' : '/api/add-like';
await axios.post(endpoint, { reviewId }, createAuthHeaders(token));
- setLikedReviews((reviews) => ({ ...reviews, [reviewId]: !dislike }));
+ setLikedReviews((reviews) => {
+ return { ...reviews, [reviewId]: !dislike };
+ });
+ setPendingReviews((reviews) =>
+ reviews.map((review) =>
+ review.id === reviewId
+ ? { ...review, likes: (review.likes || defaultLikes) + offsetLikes }
+ : review
+ )
+ );
setApprovedReviews((reviews) =>
reviews.map((review) =>
review.id === reviewId
@@ -314,7 +349,7 @@ const ProfilePage = ({ user, setUser }: Props): ReactElement => {
{/* Maps list of pending reviews and calls Review Component with fields for each user*/}
{sortReviews(pendingReviews, 'date').map((review, index) => (
-
+
{
{sortReviews(approvedReviews, 'date').map((review, index) => (
Date: Thu, 7 Nov 2024 22:45:38 -0500
Subject: [PATCH 08/10] ran prettier
---
backend/src/app.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/app.ts b/backend/src/app.ts
index aad2004b..99036f15 100644
--- a/backend/src/app.ts
+++ b/backend/src/app.ts
@@ -168,7 +168,7 @@ app.get('/api/review/like/:userId', authenticate, async (req, res) => {
throw new Error('not authenticated');
}
const realUserId = req.user.uid;
- const {userId} = req.params;
+ const { userId } = req.params;
const statusType = req.query.status;
if (userId !== realUserId) {
res.status(401).send("Error: user is not authorized to access another user's likes");
From 33769be2bd1cf5106c4d94015de9bd7f350efed5 Mon Sep 17 00:00:00 2001
From: Kea-Roy Ong <146872846+kea-roy@users.noreply.github.com>
Date: Mon, 11 Nov 2024 16:55:05 -0500
Subject: [PATCH 09/10] ensure it doesn't prompt on opening of page
---
frontend/src/pages/ApartmentPage.tsx | 2 +-
frontend/src/pages/LandlordPage.tsx | 2 +-
frontend/src/pages/ProfilePage.tsx | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/frontend/src/pages/ApartmentPage.tsx b/frontend/src/pages/ApartmentPage.tsx
index aeba454f..342c6d10 100644
--- a/frontend/src/pages/ApartmentPage.tsx
+++ b/frontend/src/pages/ApartmentPage.tsx
@@ -250,7 +250,7 @@ const ApartmentPage = ({ user, setUser }: Props): ReactElement => {
// Fetch the reviews that the user has liked and set the liked reviews and like statuses.
useEffect(() => {
- getUser(true).then((user) => {
+ getUser(false).then((user) => {
if (user) {
user.getIdToken(true).then((token) => {
get(
diff --git a/frontend/src/pages/LandlordPage.tsx b/frontend/src/pages/LandlordPage.tsx
index 42b82be4..6e105733 100644
--- a/frontend/src/pages/LandlordPage.tsx
+++ b/frontend/src/pages/LandlordPage.tsx
@@ -180,7 +180,7 @@ const LandlordPage = ({ user, setUser }: Props): ReactElement => {
// Fetch the reviews that the user has liked and set the liked reviews and like statuses.
useEffect(() => {
- getUser(true).then((user) => {
+ getUser(false).then((user) => {
if (user) {
user.getIdToken(true).then((token) => {
get(
diff --git a/frontend/src/pages/ProfilePage.tsx b/frontend/src/pages/ProfilePage.tsx
index 09ef591a..b669adb3 100644
--- a/frontend/src/pages/ProfilePage.tsx
+++ b/frontend/src/pages/ProfilePage.tsx
@@ -183,7 +183,7 @@ const ProfilePage = ({ user, setUser }: Props): ReactElement => {
// Fetch the reviews that the user has liked and set the liked reviews and like statuses.
useEffect(() => {
- getUser(true).then((user) => {
+ getUser(false).then((user) => {
if (user) {
user.getIdToken(true).then((token) => {
get(
From 5305702619068f18d295f5aa724454981de37b13 Mon Sep 17 00:00:00 2001
From: Kea-Roy Ong <146872846+kea-roy@users.noreply.github.com>
Date: Tue, 3 Dec 2024 18:48:52 -0500
Subject: [PATCH 10/10] implemented requested changes
---
backend/src/app.ts | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/backend/src/app.ts b/backend/src/app.ts
index f26ebc12..8d365cb5 100644
--- a/backend/src/app.ts
+++ b/backend/src/app.ts
@@ -181,17 +181,19 @@ app.get('/api/review/like/:userId', authenticate, async (req, res) => {
if (data) {
const reviewIds = Object.keys(data);
const matchingReviews: ReviewWithId[] = [];
- let query = reviewCollection.where(FieldPath.documentId(), 'in', reviewIds);
- if (statusType) {
- // filter by status if provided
- query = query.where('status', '==', statusType);
+ if (reviewIds.length > 0) {
+ let query = reviewCollection.where(FieldPath.documentId(), 'in', reviewIds);
+ if (statusType) {
+ // filter by status if provided
+ query = query.where('status', '==', statusType);
+ }
+ const querySnapshot = await query.get();
+ querySnapshot.forEach((doc) => {
+ const data = doc.data();
+ const reviewData = { ...data, date: data.date.toDate() };
+ matchingReviews.push({ ...reviewData, id: doc.id } as ReviewWithId);
+ });
}
- const querySnapshot = await query.get();
- querySnapshot.forEach((doc) => {
- const data = doc.data();
- const reviewData = { ...data, date: data.date.toDate() };
- matchingReviews.push({ ...reviewData, id: doc.id } as ReviewWithId);
- });
res.status(200).send(JSON.stringify(matchingReviews));
return;
}