Skip to content

Commit 811b547

Browse files
Merge branch 'dev' into ft/pi-sandbox----
2 parents c32d751 + a4368ce commit 811b547

File tree

11 files changed

+170
-77
lines changed

11 files changed

+170
-77
lines changed

context/AppContextProvider.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const AppContextProvider = ({ children }: AppContextProviderProps) => {
7171
}
7272

7373
return (
74-
<AppContext.Provider value={{ currentUser, setCurrentUser, loginUser ,autoLoginUser}}>
74+
<AppContext.Provider value={{ currentUser, setCurrentUser, loginUser, autoLoginUser}}>
7575
{children}
7676
</AppContext.Provider>
7777
);

package-lock.json

+10-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"@testing-library/jest-dom": "^6.4.2",
5050
"@testing-library/react": "^15.0.2",
5151
"@types/leaflet": "^1.9.12",
52+
"@types/lodash": "^4.17.5",
5253
"@types/node": "^20",
5354
"@types/react": "^18",
5455
"@types/react-dom": "^18",

src/app/[locale]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default function Index() {
1919
ssr: false,
2020
});
2121

22-
const { loginUser ,autoLoginUser} = useContext(AppContext);
22+
const { loginUser, autoLoginUser} = useContext(AppContext);
2323

2424
useEffect(() => {
2525
const token= localStorage.getItem('token');

src/app/[locale]/seller/registration/page.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ const SellerRegistrationForm = () => {
152152
<TrustMeter ratings={seller.trust_meter_rating} />
153153
<div className="flex items-center justify-between mt-3">
154154
<p className="text-sm">{t('SCREEN.BUY_FROM_SELLER.REVIEWS_SCORE_MESSAGE', {seller_review_rating: seller.trust_meter_rating})}</p>
155+
<Link href="/seller/reviews/userid">
155156
<OutlineBtn label={t('SHARED.CHECK_REVIEWS')} onClick={() => handleNavigation('seller/reviews')} />
157+
</Link>
156158
</div>
157159
</div>
158160
<div className="mb-7">

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

+26-9
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,15 @@ import Link from 'next/link';
44

55
import { OutlineBtn } from '@/components/shared/Forms/Buttons/Buttons';
66

7-
function SellerReviews() {
7+
function SellerReviews({
8+
params,
9+
searchParams,
10+
}: {
11+
params: any;
12+
searchParams: any;
13+
}) {
814
const t = useTranslations();
15+
const { buyer } = searchParams;
916

1017
interface ReviewInt {
1118
heading: string;
@@ -36,8 +43,8 @@ function SellerReviews() {
3643
user: 'peejenn',
3744
reaction: 'Happy',
3845
unicode: '🙂',
39-
}
40-
].concat(ReviewsInfo,ReviewsInfo,ReviewsInfo,ReviewsInfo,ReviewsInfo);
46+
},
47+
].concat(ReviewsInfo, ReviewsInfo, ReviewsInfo, ReviewsInfo, ReviewsInfo);
4148

4249
const translateReactionRating = (reaction: string): string => {
4350
switch (reaction) {
@@ -60,7 +67,9 @@ function SellerReviews() {
6067
<>
6168
<div className="px-4 py-[20px] text-[#333333] sm:max-w-[520px] w-full m-auto">
6269
<h1 className="text-[#333333] text-lg font-semibold md:font-bold md:text-2xl mb-1">
63-
{t('SCREEN.CHECK_REVIEWS_FEEDBACK.CHECK_REVIEWS_FEEDBACK_HEADER', {seller_id: 'Femma'})}
70+
{t('SCREEN.CHECK_REVIEWS_FEEDBACK.CHECK_REVIEWS_FEEDBACK_HEADER', {
71+
seller_id: 'Femma',
72+
})}
6473
</h1>
6574
{ReviewData.map((item, index) => (
6675
<div key={index} className="border-b border-[#D9D9D9] py-4">
@@ -69,12 +78,18 @@ function SellerReviews() {
6978
<p>{item.date}</p>
7079
<p>{item.time}</p>
7180
</div>
72-
<div className="text-primary mb-3">{t('SCREEN.CHECK_REVIEWS_FEEDBACK.BY_REVIEWER', {buyer_id: item.user})}</div>
81+
<div className="text-primary mb-3">
82+
{t('SCREEN.CHECK_REVIEWS_FEEDBACK.BY_REVIEWER', {
83+
buyer_id: item.user,
84+
})}
85+
</div>
7386
<div className="flex justify-between items-center">
7487
<div className="flex">
7588
<div className="mr-4">
7689
<span>{item.unicode}</span>{' '}
77-
<span className="text-sm">{translateReactionRating(item.reaction)}</span>
90+
<span className="text-sm">
91+
{translateReactionRating(item.reaction)}
92+
</span>
7893
</div>
7994
<Image
8095
src="/images/business/product.png"
@@ -83,9 +98,11 @@ function SellerReviews() {
8398
height={60}
8499
/>
85100
</div>
86-
<Link href="reviews/feedback">
87-
<OutlineBtn label={t('SHARED.REPLY')}/>
88-
</Link>
101+
{buyer == 'true' ? null : (
102+
<Link href="reviews/feedback">
103+
<OutlineBtn label={t('SHARED.REPLY')} />
104+
</Link>
105+
)}
89106
</div>
90107
</div>
91108
))}

src/app/[locale]/seller/sale-items/page.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { FileInput, TextArea } from '@/components/shared/Forms/Inputs/Inputs';
1313
import ConfirmDialog from '@/components/shared/confirm';
1414
import { PiFestJson } from '@/constants/demoAPI';
1515
import { fetchSingleSeller, createReview } from '@/services/api';
16+
import Link from 'next/link';
1617

1718
export default function Page() {
1819
const SUBHEADER = "font-bold mb-2";
@@ -191,7 +192,9 @@ export default function Page() {
191192
<p className="text-sm">
192193
{t('SCREEN.BUY_FROM_SELLER.REVIEWS_SCORE_MESSAGE', {seller_review_rating: seller.average_rating})}
193194
</p>
194-
<OutlineBtn label={t('SHARED.CHECK_REVIEWS')} onClick={() => handleNavigation('seller/reviews')} />
195+
<Link href={`/seller/reviews/userid?buyer=true`}>
196+
<OutlineBtn label={t('SHARED.CHECK_REVIEWS')} />
197+
</Link>
195198
</div>
196199
</div>
197200
<div className="mb-7">

src/components/shared/Review/emojipicker.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,23 @@ export default function EmojiPicker(props: any) {
4545

4646
return (
4747
<div>
48-
<div className='flex gap-3 w-full text-center justify-center my-2'>
49-
<div className='bg-[#DF2C2C33] rounded-md p-2'>
48+
<div className='flex flex-wrap gap-3 w-full text-center justify-center my-2'>
49+
<div className='bg-[#DF2C2C33] flex-grow-[0.5] rounded-md p-2'>
5050
<p className='text-red-700 mb-2'>{t('SHARED.REACTION_RATING.UNSAFE')}</p>
5151
<div
5252
onClick={() => !props.clickDisabled ? handleEmojiClick(despairEmoji.value) : undefined}
5353
className={`${selectedEmoji !== despairEmoji.value ? 'bg-red-200' : 'bg-red-700'} outline-[#DF2C2C] ${emojiBtnClass}`}
5454
>
5555
<div>
56-
<p className='text-3xl py-2'>{despairEmoji.unicode}</p>
56+
<p className='text-3xl md:py-2 py-1'>{despairEmoji.unicode}</p>
5757
<p className='md:text-[16px] text-[14px]'>{despairEmoji.name}</p>
5858
{props.reviews && (
5959
<p>{getReview(props.reviews, despairEmoji.name)}</p>
6060
)}
6161
</div>
6262
</div>
6363
</div>
64-
<div className='bg-[#3D924A8A] rounded-[10px] w-full p-2 text-center text-white'>
64+
<div className='bg-[#3D924A8A] rounded-[10px] flex-grow-[4.3] flex-4 p-2 text-center text-white'>
6565
<p className='mb-2'>{t('SHARED.REACTION_RATING.TRUSTWORTHY')}</p>
6666
<div id='emoji-picker' className='flex gap-3 justify-center'>
6767
{emojis.map((emoji, index) => (

src/components/shared/map/Map.tsx

+118-30
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,158 @@
1-
import L from 'leaflet';
2-
import React, { useEffect, useState } from 'react';
1+
import { useEffect, useState, useCallback } from 'react';
32
import {
43
MapContainer,
54
Marker,
65
Popup,
76
TileLayer,
87
useMapEvents,
98
} from 'react-leaflet';
9+
import L from 'leaflet';
10+
import { LatLngExpression, LatLngBounds } from 'leaflet';
11+
import _ from 'lodash';
12+
1013
import MapMarkerPopup from './MapMarkerPopup';
1114
import { dummyCoordinates } from '../../../constants/coordinates';
12-
import { Button, YellowBtn } from '../Forms/Buttons/Buttons';
13-
import { IoMdAdd } from 'react-icons/io';
14-
import { FaLocationCrosshairs } from 'react-icons/fa6';
15-
import { LatLng } from 'leaflet';
16-
import Image from 'next/image';
1715

18-
function Map() {
16+
// Mock function to simulate fetching initial coordinates
17+
const fetchSellerCoordinates = async (origin: { lat: number; lng: number }, radius: number): Promise<LatLngExpression[]> => {
18+
console.log('Fetching initial coordinates with origin:', origin, 'and radius:', radius);
19+
20+
// Replace this mock function with the actual API call
21+
// const response = await axios.get('/api/sellers', {
22+
// params: { origin, radius }
23+
// });
24+
// return response.data;
25+
26+
return new Promise((resolve) => {
27+
setTimeout(() => {
28+
console.log('Initial coordinates fetched:', dummyCoordinates);
29+
resolve(dummyCoordinates);
30+
}, 500);
31+
});
32+
};
33+
34+
// Mock function to simulate fetching additional data based on the map bounds
35+
const fetchAdditionalSellerData = async (center: { lat: number; lng: number }, radius: number): Promise<LatLngExpression[]> => {
36+
console.log('Fetching additional seller data with center:', center, 'and radius:', radius);
37+
38+
// Replace this mock function with the actual API call
39+
// const response = await axios.get('/api/sellers/additional', {
40+
// params: { center, radius }
41+
// });
42+
// return response.data;
43+
44+
return new Promise((resolve) => {
45+
setTimeout(() => {
46+
const additionalData = dummyCoordinates.slice(0, 10); // Simulate fetching a subset of data
47+
resolve(additionalData);
48+
}, 500);
49+
});
50+
};
51+
52+
const Map = () => {
1953
const customIcon = L.icon({
2054
iconUrl: '/favicon-32x32.png',
2155
iconSize: [32, 32],
2256
iconAnchor: [12, 41],
2357
popupAnchor: [1, -34],
2458
});
2559

26-
const [position, setPosition] = useState<LatLng | null>(null);
60+
const [position, setPosition] = useState<L.LatLng | null>(null);
61+
const [sellerCoordinates, setSellerCoordinates] = useState<LatLngExpression[]>([]);
62+
const [origin, setOrigin] = useState({ lat: -1.6279, lng: 29.7451 });
63+
const [radius, setRadius] = useState(5); // Initial radius in km
64+
const [loading, setLoading] = useState(false);
65+
const [error, setError] = useState<string | null>(null);
66+
67+
useEffect(() => {
68+
fetchInitialCoordinates();
69+
}, []);
70+
71+
const fetchInitialCoordinates = async () => {
72+
setLoading(true);
73+
setError(null);
74+
try {
75+
const coordinates = await fetchSellerCoordinates(origin, radius);
76+
setSellerCoordinates(coordinates);
77+
} catch (err) {
78+
setError('Failed to fetch initial coordinates');
79+
} finally {
80+
setLoading(false);
81+
}
82+
};
83+
84+
const handleMapInteraction = async (newBounds: L.LatLngBounds) => {
85+
const newCenter = newBounds.getCenter();
86+
const newRadius = calculateRadius(newBounds);
87+
setLoading(true);
88+
setError(null);
89+
try {
90+
const additionalData = await fetchAdditionalSellerData({ lat: newCenter.lat, lng: newCenter.lng }, newRadius);
91+
if (additionalData.length > 0) {
92+
setSellerCoordinates((prevCoordinates) => {
93+
const newCoordinates = [...prevCoordinates, ...additionalData];
94+
return newCoordinates;
95+
});
96+
} else {
97+
console.warn('No additional seller data found for the new bounds.');
98+
}
99+
} catch (err) {
100+
setError('Failed to fetch additional data');
101+
} finally {
102+
setLoading(false);
103+
}
104+
};
105+
106+
const calculateRadius = (bounds: L.LatLngBounds) => {
107+
// Implement logic to calculate radius based on map bounds
108+
return 10; // Example radius value
109+
};
110+
111+
const debouncedHandleMapInteraction = useCallback(
112+
_.debounce((bounds: LatLngBounds) => {
113+
handleMapInteraction(bounds);
114+
}, 500),
115+
[]
116+
);
117+
27118
function LocationMarker() {
28119
const map = useMapEvents({
29-
// layeradd() {
30-
// map.locate();
31-
// },
32-
// click() {
33-
// map.locate();
34-
// },
35120
locationfound(e) {
36121
setPosition(e.latlng);
37122
map.flyTo(e.latlng, map.getZoom());
38123
},
124+
moveend() {
125+
const bounds = map.getBounds();
126+
debouncedHandleMapInteraction(bounds);
127+
},
128+
zoomend() {
129+
const bounds = map.getBounds();
130+
debouncedHandleMapInteraction(bounds);
131+
},
39132
});
40133

41-
return (
42-
<>
43-
44-
{position === null ? null : (
45-
<Marker position={position}>
46-
<Popup>You are here</Popup>
47-
</Marker>
48-
)}
49-
</>
134+
return position === null ? null : (
135+
<Marker position={position}>
136+
<Popup>You are here</Popup>
137+
</Marker>
50138
);
51139
}
52140

53141
return (
54142
<>
143+
{loading && <div className="loading">Loading...</div>}
144+
{error && <div className="error">{error}</div>}
55145
<MapContainer
56-
center={{ lat: -1.6279, lng: 29.7451 }}
146+
center={origin}
57147
zoom={13}
58148
zoomControl={false}
59-
// scrollWheelZoom={false}
60-
className="w-full flex-1 fixed top-[76.19px] h-[calc(100vh-76.19px)] left-0 right-0 bottom-0">
149+
className="w-full flex-1 fixed top-[90px] h-[calc(100vh-55px)] left-0 right-0 bottom-0">
61150
<TileLayer
62151
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
63152
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
64153
/>
65154
<LocationMarker />
66-
{dummyCoordinates.map((coord, i) => (
155+
{sellerCoordinates.map((coord, i) => (
67156
<Marker position={coord} key={i} icon={customIcon}>
68157
<Popup closeButton={false}>
69158
<MapMarkerPopup />
@@ -72,7 +161,6 @@ function Map() {
72161
))}
73162
</MapContainer>
74163
</>
75-
);
76-
}
164+
)};
77165

78166
export default Map;

src/components/shared/sidebar/sidebar.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ function Sidebar(props: any) {
168168
props.setToggleDis(false) // Close sidebar on click
169169
}}
170170
/>
171-
<Link href="/seller/reviews">
171+
<Link href="/seller/reviews/userid">
172172
<Button
173173
label={t('SHARED.CHECK_REVIEWS')}
174174
styles={{

0 commit comments

Comments
 (0)