Skip to content

Commit

Permalink
핑 새로고침 기능 구현 (#72)
Browse files Browse the repository at this point in the history
* [feature] 업데이트 기능 구현

* [feature] 빌드 오류 수정
  • Loading branch information
choihooo authored Nov 24, 2024
1 parent 2b9a854 commit 11991b5
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 75 deletions.
26 changes: 20 additions & 6 deletions fe/public/pin/recommendPing.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fe/public/profile/Card/Map/pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions fe/public/profile/Card/Map/pin.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 8 additions & 22 deletions fe/public/profile/level4.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 89 additions & 12 deletions fe/src/app/event-maps/[id]/components/BottomDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { RecommendButton } from "./RecommendButton";
import { RecommendInActive } from "./RecommendInActive";
import LocationButton from "./LocationButton";
import { RecommendActive } from "./RecommendActive";
import useUpdateTimeStore from "../stores/useUpdateTime";

interface NonMember {
nonMemberId: number;
Expand All @@ -32,6 +33,15 @@ interface BottomDrawerProps {
}

interface RecommendPing {
placeName: string;
sid: string;
px: number;
py: number;
url: string;
type: string;
}

interface CustomRecommendPing {
iconLevel: number;
placeName: string;
sid: string;
Expand All @@ -50,10 +60,13 @@ export function BottomDrawer({
const [selectedButton, setSelectedButton] = useState<number | null>(null);
const [nonMembers, setNonMembers] = useState<NonMember[]>(initialNonMembers);
const [allPings, setAllPings] = useState<Ping[]>([]);
const [recommendPings, setrecommendPings] = useState<RecommendPing[]>([]);
const [isRecommend, setIsRecommend] = useState<boolean>(false);
const [isRecommended, setIsRecommended] = useState<boolean>(false);
const [neighborhood, setNeighborhood] = useState<string>("");
const [nonRecommend, setNonRecommend] = useState<boolean>(false);
const [trigger, setTrigger] = useState<boolean>(false);
const { setUpdateTime } = useUpdateTimeStore();

const { setCustomMarkers } = useMarkerStore();
const moveToLocation = useLocationStore((state) => state.moveToLocation);
Expand All @@ -73,7 +86,7 @@ export function BottomDrawer({
if (data.recommendPings && data.recommendPings.length > 0) {
setIsRecommended(true);
recommendProfile = data.recommendPings.map(
(ping: RecommendPing) => ({
(ping: CustomRecommendPing) => ({
iconLevel: 10, // Fixed icon level
nonMembers: [
{
Expand Down Expand Up @@ -104,13 +117,14 @@ export function BottomDrawer({
...(recommendProfile || []), // recommendProfile 추가
]);
setNeighborhood(data.neighborhood);
console.log(data);
}
} catch (error) {
console.error("Error:", error);
}
};
fetchAllPings();
}, [apiUrl, id, setCustomMarkers]);
}, [apiUrl, id, setCustomMarkers, trigger]);

const handleLocationClick = () => {
if (navigator.geolocation) {
Expand All @@ -124,11 +138,38 @@ export function BottomDrawer({
}
};

const handleRecommendAllowClick = () => {
setIsRecommend(true);
const handleAddToMorphing = async () => {
const uuid = id; // id를 uuid로 설정
const sids = recommendPings.map((item) => item.sid); // sid 값만 추출

const requestBody = {
uuid, // 문자열로 uuid 설정
sids, // 추출한 sid 배열
};

try {
const response = await fetch(`${apiUrl}/nonmembers/pings/recommend`, {
method: "POST",
headers: {
"Content-Type": "application/json;charset=UTF-8",
},
body: JSON.stringify(requestBody),
});

if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

const result = await response.json(); // 응답 데이터 처리
console.log("Recommended Data Response:", result);
setTrigger((prev) => !prev);
setIsRecommend(false); // 추천 모드 비활성화
} catch (error) {
console.error("Error fetching recommended data:", error);
}
};

const handleAddToMorphing = async () => {
const handleRecommendShowClick = async () => {
const Km = 1.0;
let found = false;

Expand All @@ -139,11 +180,13 @@ export function BottomDrawer({
);
if (response.ok) {
const data = await response.json();
console.log(data);
if (data.recommendPings.length === 0) {
setNonRecommend(true);
} else if (data.recommendPings.length >= 5) {
setCustomMarkers(data.recommendPings);
found = true;
setrecommendPings(data.recommendPings);
setIsRecommend(found);
}
} else {
Expand Down Expand Up @@ -181,14 +224,48 @@ export function BottomDrawer({
const handleRefresh = async () => {
try {
const response = await fetch(
`${apiUrl}/nonmembers/pings/refresh?uuid=${id}`
`${apiUrl}/nonmembers/pings/refresh-all?uuid=${id}`,
{ method: "GET" }
);
if (response.ok) {
const data = await response.json();
setEventName(data.eventName);
setNonMembers(data.nonMembers);
setAllPings(data.pings || []);
setCustomMarkers(data.pings || []);
let recommendProfile = [];
if (data.recommendPings && data.recommendPings.length > 0) {
setIsRecommended(true);

recommendProfile = data.recommendPings.map(
(ping: CustomRecommendPing) => ({
iconLevel: 10, // Fixed icon level
nonMembers: [
{
nonMemberId: -1,
name: "추천 모핑", // Fixed name
profileSvg: "/profile/recommendProfile.svg", // Fixed profileSvg
},
],
url: ping.url,
placeName: ping.placeName,
px: ping.px,
py: ping.py,
type: ping.type,
})
);
}
setEventName(data.eventName || "");
setNonMembers([
...(recommendProfile[0]?.nonMembers || []),
...(data.nonMembers || []),
]);
setAllPings([
...(data.pings || []), // 기존 pings
...(recommendProfile || []), // recommendProfile 추가
]);
setCustomMarkers([
...(data.pings || []), // 기존 pings
...(recommendProfile || []), // recommendProfile 추가
]);
setNeighborhood(data.neighborhood);
setUpdateTime(data.pingLastUpdateTime);
} else {
console.error("Failed to fetch refreshed data:", response.status);
}
Expand All @@ -201,11 +278,11 @@ export function BottomDrawer({
<div
role="button"
tabIndex={0}
className="bottom-drawer w-full h-[760px] bg-grayscale-90 z-10 rounded-t-xlarge"
className="bottom-drawer w-full h-[760px] bg-grayscale-90 z-10 rounded-t-xlarge border-none"
>
{!isRecommend && !isRecommended && (
<div className="absolute ml-[16px] left-0 -top-[60px] flex">
<RecommendButton onClick={handleRecommendAllowClick} />
<RecommendButton onClick={handleRecommendShowClick} />
</div>
)}
<div className="absolute mr-[16px] right-0 -top-[60px] flex">
Expand Down
1 change: 1 addition & 0 deletions fe/src/app/event-maps/[id]/components/MapComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ export default function MapComponent({
false
)
);

previousMarkerIndexRef.current = null;
}

Expand Down
9 changes: 7 additions & 2 deletions fe/src/app/event-maps/[id]/components/RecommendInActive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export function RecommendInActive({
}: RecommendInActiveProps): JSX.Element {
const router = useRouter();

// iconLevel에 따라 내림차순으로 정렬
const sortedPings = [...allPings].sort((a, b) => b.iconLevel - a.iconLevel);

return (
<>
<div className="h-[62px] w-full pt-[16px] pb-[14px] pl-[20px] pr-[16px] flex justify-between text-lg text-grayscale-0 font-300">
Expand Down Expand Up @@ -91,14 +94,16 @@ export function RecommendInActive({
))}
</div>
<div className="h-[484px] flex flex-col gap-[12px] p-[20px] overflow-auto mt-[20px]">
{allPings.map((ping, index) => (
{sortedPings.map((ping, index) => (
<StoreItem
key={ping.url}
url={ping.url}
name={ping.placeName}
type={ping.type}
iconLevel={ping.iconLevel}
ref={index === allPings.length - 1 ? lastPingElementRef : undefined}
ref={
index === sortedPings.length - 1 ? lastPingElementRef : undefined
}
/>
))}
</div>
Expand Down
69 changes: 38 additions & 31 deletions fe/src/app/event-maps/[id]/components/StoreItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { forwardRef } from "react";
import React, { forwardRef, useState } from "react";
import Image from "next/image";

interface StoreItemProps {
Expand All @@ -9,38 +9,45 @@ interface StoreItemProps {
}

const StoreItem = forwardRef<HTMLDivElement, StoreItemProps>(
({ name, type, url, iconLevel }, ref) => (
<div
ref={ref}
className="w-auto h-[56px] bg-[#2d2d2d] p-[8px] flex rounded justify-between store-item scrollbar-hide"
>
<div className="flex gap-[12px]">
<Image
src={`/profile/level${iconLevel}.svg`}
onError={(e) => {
e.currentTarget.src = "/profile/default.svg"; // Fallback to a default image
}}
alt="edit"
width={40}
height={40}
/>
<div>
<div className="text-divider-default text-text-md1">{name}</div>
<div className="text-text-disabled text-caption">{type}</div>
({ name, type, url, iconLevel }, ref) => {
const [imageSrc, setImageSrc] = useState(`/profile/level${iconLevel}.svg`);

return (
<div
ref={ref}
className="w-auto h-[56px] bg-[#2d2d2d] p-[8px] flex rounded justify-between store-item scrollbar-hide"
>
<div className="flex gap-[12px]">
<Image
src={imageSrc}
onError={() => setImageSrc("/profile/recommendProfile.svg")}
alt="pin"
width={40}
height={40}
/>
<div>
<div className="text-divider-default text-text-md1">{name}</div>
<div className="text-text-disabled text-caption">{type}</div>
</div>
</div>
<button
type="button"
onClick={() => {
window.location.href = url;
}}
className="flex justify-center items-center text-text-disabled text-caption"
>
상세정보
<Image
src="/svg/rightArrow.svg"
alt="화살표"
width={12}
height={24}
/>
</button>
</div>
<button
type="button" // 명시적으로 버튼 타입 설정
onClick={() => {
window.location.href = url; // window.location.href로 수정
}}
className="flex justify-center items-center text-text-disabled text-caption"
>
상세정보
<Image src="/svg/rightArrow.svg" alt="화살표" width={12} height={24} />
</button>
</div>
)
);
}
);

export default StoreItem;
Loading

0 comments on commit 11991b5

Please sign in to comment.