Skip to content

Commit 3d1b6f6

Browse files
authored
Merge pull request #265 from map-of-pi/search-reviews
Approved (1).
2 parents 4b96bbd + ee6cfe6 commit 3d1b6f6

File tree

10 files changed

+120
-68
lines changed

10 files changed

+120
-68
lines changed

messages/en-GB.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@
8686
"REVIEWS_HEADER": "Reviews",
8787
"GIVE_REVIEW_SECTION_HEADER": "Give review to this pioneer",
8888
"REVIEWS_GIVEN_SECTION_HEADER": "Reviews given by this pioneer",
89-
"REVIEWS_RECEIVED_SECTION_HEADER": "Reviews received by this pioneer"
89+
"REVIEWS_RECEIVED_SECTION_HEADER": "Reviews received by this pioneer",
90+
"VALIDATION": {
91+
"NO_REVIEWS_FOUND": "No reviews found for Pioneer {search_value}",
92+
"NO_PIONEER_FOUND": "Pioneer {search_value} not found"
93+
}
9094
},
9195
"CHECK_REVIEWS_FEEDBACK": {
9296
"CHECK_REVIEWS_NO_FEEDBACK_HEADER": "No reviews for {seller_id}",

messages/en.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,11 @@
8787
"REVIEWS_HEADER": "Reviews",
8888
"GIVE_REVIEW_SECTION_HEADER": "Give review to this pioneer",
8989
"REVIEWS_GIVEN_SECTION_HEADER": "Reviews given by this pioneer",
90-
"REVIEWS_RECEIVED_SECTION_HEADER": "Reviews received by this pioneer"
90+
"REVIEWS_RECEIVED_SECTION_HEADER": "Reviews received by this pioneer",
91+
"VALIDATION": {
92+
"NO_REVIEWS_FOUND": "No reviews found for Pioneer {search_value}",
93+
"NO_PIONEER_FOUND": "Pioneer {search_value} not found"
94+
}
9195
},
9296
"CHECK_REVIEWS_FEEDBACK": {
9397
"CHECK_REVIEWS_NO_FEEDBACK_HEADER": "No reviews for {seller_id}",

messages/es.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@
8686
"REVIEWS_HEADER": "Reseñas",
8787
"GIVE_REVIEW_SECTION_HEADER": "Dar una reseña a este pionero",
8888
"REVIEWS_GIVEN_SECTION_HEADER": "Reseñas dadas por este pionero",
89-
"REVIEWS_RECEIVED_SECTION_HEADER": "Reseñas recibidas por este pionero"
89+
"REVIEWS_RECEIVED_SECTION_HEADER": "Reseñas recibidas por este pionero",
90+
"VALIDATION": {
91+
"NO_REVIEWS_FOUND": "No se encontraron reseñas para el Pionero {search_value}",
92+
"NO_PIONEER_FOUND": "Pionero {search_value} no encontrado"
93+
}
9094
},
9195
"CHECK_REVIEWS_FEEDBACK": {
9296
"CHECK_REVIEWS_NO_FEEDBACK_HEADER": "No hay reseñas para {seller_id}",

messages/ewe-BJ.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@
8686
"REVIEWS_HEADER": "Nenyíawo",
8787
"GIVE_REVIEW_SECTION_HEADER": "No wo review kplii ame siaa",
8888
"REVIEWS_GIVEN_SECTION_HEADER": "Reviewwo kplii ame siaa",
89-
"REVIEWS_RECEIVED_SECTION_HEADER": "Reviewwo yi le ame siaa"
89+
"REVIEWS_RECEIVED_SECTION_HEADER": "Reviewwo yi le ame siaa",
90+
"VALIDATION": {
91+
"NO_REVIEWS_FOUND": "Mèɖu nú ŋutɔ wòàdzra Pioné {search_value}",
92+
"NO_PIONEER_FOUND": "Pioné {search_value} wòɖu nɔ anyi"
93+
}
9094
},
9195
"CHECK_REVIEWS_FEEDBACK": {
9296
"CHECK_REVIEWS_NO_FEEDBACK_HEADER": "Mèkpɔ dzudzɔkpɔkpɔ ƒe {seller_id} o",

messages/hau-NG.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@
8686
"REVIEWS_HEADER": "Bita",
8787
"GIVE_REVIEW_SECTION_HEADER": "Ba wa wannan jagora sharhi",
8888
"REVIEWS_GIVEN_SECTION_HEADER": "Sharhi da aka ba wannan jagora",
89-
"REVIEWS_RECEIVED_SECTION_HEADER": "Sharhi da wannan jagora ya samu"
89+
"REVIEWS_RECEIVED_SECTION_HEADER": "Sharhi da wannan jagora ya samu",
90+
"VALIDATION": {
91+
"NO_REVIEWS_FOUND": "Ba a sami bita ga Mai-tushen {search_value} ba",
92+
"NO_PIONEER_FOUND": "Ba a sami Mai-tushen {search_value} ba"
93+
}
9094
},
9195
"CHECK_REVIEWS_FEEDBACK": {
9296
"CHECK_REVIEWS_NO_FEEDBACK_HEADER": "Babu bita don {seller_id}",

messages/ko.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@
8686
"REVIEWS_HEADER": "리뷰",
8787
"GIVE_REVIEW_SECTION_HEADER": "이 개척자에게 리뷰 남기기",
8888
"REVIEWS_GIVEN_SECTION_HEADER": "이 개척자가 남긴 리뷰",
89-
"REVIEWS_RECEIVED_SECTION_HEADER": "이 개척자가 받은 리뷰"
89+
"REVIEWS_RECEIVED_SECTION_HEADER": "이 개척자가 받은 리뷰",
90+
"VALIDATION": {
91+
"NO_REVIEWS_FOUND": "개척자 {search_value}에 대한 리뷰를 찾을 수 없습니다",
92+
"NO_PIONEER_FOUND": "개척자 {search_value}를 찾을 수 없습니다"
93+
}
9094
},
9195
"CHECK_REVIEWS_FEEDBACK": {
9296
"CHECK_REVIEWS_NO_FEEDBACK_HEADER": "{seller_id}에 대한 리뷰가 없습니다",

src/app/[locale]/seller/reviews/[id]/page.tsx

Lines changed: 79 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useTranslations } from 'next-intl';
44
import Image from 'next/image';
55
import Link from 'next/link';
66
import { useEffect, useState, useRef, useContext } from 'react';
7-
import { AppContext } from '../../../../../../context/AppContextProvider';
7+
import { toast } from 'react-toastify';
88
import { resolveRating } from '../util/ratingUtils';
99
import { OutlineBtn } from '@/components/shared/Forms/Buttons/Buttons';
1010
import EmojiPicker from '@/components/shared/Review/emojipicker';
@@ -15,6 +15,7 @@ import SearchIcon from '@mui/icons-material/Search';
1515
import { FormControl, TextField } from '@mui/material';
1616
import { fetchReviews } from '@/services/reviewsApi';
1717
import { resolveDate } from '@/utils/date';
18+
import { AppContext } from '../../../../../../context/AppContextProvider';
1819
import logger from '../../../../../../logger.config.mjs';
1920

2021
function SellerReviews({
@@ -36,89 +37,109 @@ function SellerReviews({
3637
const { currentUser, setReload, reload } = useContext(AppContext);
3738
const inputRef = useRef<HTMLInputElement>(null);
3839
const [searchBarValue, setSearchBarValue] = useState('');
40+
const [toUser, setToUser] = useState('');
3941

4042
// Reusable function to process and filter reviews
41-
const processReviews = (data: IReviewOutput[], userId: string): { giverReviews: ReviewInt[], receiverReviews: ReviewInt[] } => {
43+
const processReviews = (data: IReviewOutput[]): ReviewInt[] => {
4244
const reviews = data
4345
.map((feedback: IReviewOutput) => {
44-
if (feedback.review_giver_id === userId || feedback.review_receiver_id === userId) {
45-
const { date, time } = resolveDate(feedback.review_date);
46-
const { reaction, unicode } = resolveRating(feedback.rating) || {};
47-
48-
return {
49-
heading: feedback.comment,
50-
date,
51-
time,
52-
giver: feedback.giver,
53-
receiver: feedback.receiver,
54-
giverId: feedback.review_giver_id,
55-
receiverId: feedback.review_receiver_id,
56-
reviewId: feedback._id,
57-
reaction,
58-
unicode
59-
};
60-
}
61-
return null; // Ignore irrelevant reviews
46+
const { date, time } = resolveDate(feedback.review_date);
47+
const { reaction, unicode } = resolveRating(feedback.rating) || {};
48+
return {
49+
heading: feedback.comment,
50+
date,
51+
time,
52+
giver: feedback.giver,
53+
receiver: feedback.receiver,
54+
giverId: feedback.review_giver_id,
55+
receiverId: feedback.review_receiver_id,
56+
reviewId: feedback._id,
57+
reaction,
58+
unicode,
59+
image: feedback.image
60+
};
6261
})
6362
.filter((review): review is ReviewInt => review !== null);
6463

65-
// Separate into giver and receiver reviews
66-
return {
67-
giverReviews: reviews.filter((review) => review.giverId === userId),
68-
receiverReviews: reviews.filter((review) => review.receiverId === userId)
69-
};
64+
return reviews;
7065
};
7166

72-
useEffect(() => {
73-
const fetchSellerReviews = async () => {
74-
setError(null);
75-
try {
76-
logger.info(`Fetching reviews for seller ID: ${userId}`);
77-
const data = await fetchReviews(userId);
67+
const fetchUserReviews = async () => {
68+
setError(null);
69+
try {
70+
logger.info(`Fetching reviews for userID: ${userId}`);
71+
const data = await fetchReviews(userId);
7872

79-
if (data && data.length > 0) {
80-
logger.info(`Fetched ${data.length} reviews for seller ID: ${userId}`);
81-
const { giverReviews, receiverReviews } = processReviews(data, userId);
82-
setGiverReviews(giverReviews);
83-
setReceiverReviews(receiverReviews);
73+
if (data) {
74+
if (data.givenReviews.length > 0) {
75+
logger.info(`Fetched ${data.givenReviews.length} reviews given by userID: ${userId}`);
76+
setGiverReviews(processReviews(data.givenReviews));
77+
setToUser(userId);
8478
} else {
85-
logger.warn(`No reviews found for seller ID: ${userId}`);
79+
logger.warn(`No given reviews found for userID: ${userId}`);
8680
setGiverReviews([]);
87-
setReceiverReviews([]);
8881
}
89-
} catch (error) {
90-
logger.error(`Error fetching reviews for seller ID: ${userId}`, { error });
91-
setError('Error fetching reviews. Please try again later.');
92-
} finally {
93-
setLoading(false);
94-
setReload(false);
82+
83+
if (data.receivedReviews.length > 0) {
84+
logger.info(`Fetched ${data.receivedReviews.length} reviews received by userID: ${userId}`);
85+
setReceiverReviews(processReviews(data.receivedReviews));
86+
} else {
87+
logger.warn(`No received reviews found for userID: ${userId}`);
88+
setReceiverReviews([]);
89+
}
90+
} else {
91+
logger.warn(`No reviews found for userID: ${userId}`);
92+
setGiverReviews([]);
93+
setReceiverReviews([]);
9594
}
96-
};
95+
} catch (error) {
96+
logger.error(`Error fetching reviews for userID: ${userId}`, { error });
97+
setError('Error fetching reviews. Please try again later.');
98+
} finally {
99+
setLoading(false);
100+
setReload(false);
101+
}
102+
};
97103

98-
fetchSellerReviews();
99-
}, [userId, currentUser, reload]);
104+
useEffect(() => {
105+
fetchUserReviews();
106+
}, [userId, currentUser]);
100107

101108
// Handle search logic
102109
const handleSearch = async () => {
103110
setReload(true);
104111
setError(null);
105112
try {
106-
logger.info(`Searching reviews for seller ID: ${userId} with query: ${searchBarValue}`);
113+
logger.info(`Searching reviews for userID: ${userId} with query: ${searchBarValue}`);
107114
const data = await fetchReviews(userId, searchBarValue);
108115

109-
if (data && data.length > 0) {
110-
logger.info(`Found ${data.length} reviews for seller ID: ${userId}`);
111-
const { giverReviews, receiverReviews } = processReviews(data, userId);
112-
setGiverReviews(giverReviews);
113-
setReceiverReviews(receiverReviews);
116+
if (data) {
117+
if (data.givenReviews.length > 0) {
118+
logger.info(`Found ${data.givenReviews.length} reviews given by Pioneer: ${searchBarValue}`);
119+
setGiverReviews(processReviews(data.givenReviews));
120+
setToUser(data.givenReviews[0].review_giver_id);
121+
} else {
122+
logger.warn(`No given reviews found for Pioneer: ${searchBarValue}`);
123+
setGiverReviews([]);
124+
}
125+
if (data.receivedReviews.length > 0) {
126+
logger.info(`Found ${data.receivedReviews.length} reviews received by Pioneer: ${searchBarValue}`);
127+
setReceiverReviews(processReviews(data.receivedReviews));
128+
setToUser(data.givenReviews[0].review_receiver_id);
129+
} else {
130+
logger.warn(`No given reviews found for Pioneer: ${searchBarValue}`);
131+
setReceiverReviews([]);
132+
}
133+
114134
} else {
115-
logger.warn(`No reviews found for seller ID: ${userId} with query: ${searchBarValue}`);
135+
toast.error(t('SCREEN.REVIEWS.VALIDATION.NO_REVIEWS_FOUND', { search_value: searchBarValue }));
136+
logger.warn(`No reviews found for Pioneer: ${searchBarValue}`);
116137
setGiverReviews([]);
117138
setReceiverReviews([]);
118139
}
119140
} catch (error) {
120-
logger.error(`Error searching reviews for seller ID: ${userId}`, { error });
121-
setError('Error searching reviews. Please try again later.');
141+
logger.error(`Pioneer ${searchBarValue} not found`, { error });
142+
return toast.error(t('SCREEN.REVIEWS.VALIDATION.NO_PIONEER_FOUND', { search_value: searchBarValue }));
122143
} finally {
123144
setReload(false);
124145
}
@@ -170,7 +191,7 @@ function SellerReviews({
170191

171192
<ToggleCollapse header={t('SCREEN.REVIEWS.GIVE_REVIEW_SECTION_HEADER')}>
172193
<div>
173-
<EmojiPicker sellerId={userId} setIsSaveEnabled={setIsSaveEnabled} currentUser={currentUser} setReload={setReload} />
194+
<EmojiPicker sellerId={toUser} setIsSaveEnabled={setIsSaveEnabled} currentUser={currentUser} setReload={setReload} refresh={fetchUserReviews} />
174195
</div>
175196
</ToggleCollapse>
176197
<ToggleCollapse header={t('SCREEN.REVIEWS.REVIEWS_GIVEN_SECTION_HEADER')}>
@@ -207,7 +228,7 @@ function SellerReviews({
207228
</p>
208229
</div>
209230
<div className="flex justify-between items-center">
210-
<Link href={`/seller/reviews/feedback/${review.reviewId}?seller_name=${review.giver}`}>
231+
<Link href={`/seller/reviews/feedback/${review.reviewId}?user_name=${review.giver}`}>
211232
<OutlineBtn label={t('SHARED.REPLY')} />
212233
</Link>
213234
</div>

src/components/shared/Review/emojipicker.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ export default function EmojiPicker(props: any) {
119119
const newReview = await createReview(formDataToSend);
120120
if (newReview) {
121121
toast.success(t('SHARED.REACTION_RATING.VALIDATION.SUCCESSFUL_REVIEW_SUBMISSION'));
122-
props.setReload(true)
122+
props.setReload(true);
123+
props.refresh()
123124
logger.info('Review submitted successfully');
124125
}
125126
resetReview();

src/components/shared/map/Map.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useTranslations } from 'next-intl';
2+
import Image from 'next/image';
23
import React, { useEffect, useState, useCallback, useContext, useRef } from 'react';
34
import { MapContainer, Marker, Popup, TileLayer, useMapEvents } from 'react-leaflet';
45
import L, { LatLngExpression, LatLngBounds, LatLngTuple } from 'leaflet';
@@ -302,7 +303,12 @@ const Map = ({
302303
{isSigningInUser ? (
303304
<div className="w-full flex-1 fixed bottom-0 h-[calc(100vh-76.19px)] left-0 right-0 bg-[#f5f1e6] ">
304305
<div className="flex justify-center items-center w-full h-full">
305-
<img src="/default.png" width={120} height={140} alt="splashscreen" />
306+
<Image
307+
src="/default.png"
308+
width={120}
309+
height={140}
310+
alt="splashscreen"
311+
/>
306312
</div>
307313
</div>
308314
) : (

src/components/shared/map/MapCenter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,14 @@ const MapCenter = ({ entryType }: MapCenterProps) => {
225225
</div>
226226
{/* Static Scope - should always be centered */}
227227
<div className="absolute z-10 pointer-events-none top-[54.2%] left-[49.4%] transform -translate-x-1/2 -translate-y-1/2 w-20 h-20 sm:w-16 sm:h-16">
228-
<img
228+
<Image
229229
src="/images/icons/scope.png"
230-
alt="Scope"
231230
className="w-full h-full"
232231
style={{
233232
width: '65px',
234233
height: '65px'
235234
}}
235+
alt="Scope"
236236
/>
237237
</div>
238238
{showPopup && (

0 commit comments

Comments
 (0)