Skip to content

Commit c5cd844

Browse files
authored
Merge pull request #41 from FourPointSevenFive/yoojin
fix(fe) - fix video
2 parents e060616 + 7c8e82d commit c5cd844

File tree

6 files changed

+446
-18
lines changed

6 files changed

+446
-18
lines changed

frontend/app/map/[id]/page.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { Session } from "next-auth";
1818
import stampIcon from "@/public/icons/stamp.png";
1919
import PhotoUploader from "@/app/_components/PhotoUploader";
2020
import { useSession } from "next-auth/react";
21+
import YouTube, { YouTubeProps } from "react-youtube";
2122

2223
interface LocationImage {
2324
id: number;
@@ -47,6 +48,8 @@ export default function Page() {
4748
</div>
4849
<div className="w-full">
4950
<ImageCarousel images={loc?.images} />
51+
52+
<VideoInfo videoLink={loc?.video_link ?? ""} />
5053
</div>
5154
<p className="mb-6 self-start text-sm text-neutral-700">
5255
{loc?.description}
@@ -274,3 +277,50 @@ function ImageCarousel({ images }: { images: LocationImage[] | undefined }) {
274277
</Carousel>
275278
);
276279
}
280+
281+
function extractYoutubeId({ videoLink }: { videoLink: string }) {
282+
try {
283+
const url = new URL(videoLink);
284+
285+
// 1. 짧은 URL 형태 처리 (youtu.be)
286+
if (url.hostname === "youtu.be") {
287+
return url.pathname.slice(1); // 첫 번째 슬래시 제거하고 ID 반환
288+
}
289+
290+
// 2. 일반 URL 형태 처리 (www.youtube.com)
291+
if (url.hostname.includes("youtube.com")) {
292+
const urlParams = new URLSearchParams(url.search);
293+
return urlParams.get("v");
294+
}
295+
296+
return null; // 유효하지 않은 YouTube URL
297+
} catch (error) {
298+
console.error("Invalid YouTube URL:", videoLink, error);
299+
return null;
300+
}
301+
}
302+
303+
function VideoInfo({ videoLink }: { videoLink: string }) {
304+
//youtube id 추출
305+
const youtubeId = videoLink ? extractYoutubeId({ videoLink }) : " ";
306+
307+
console.log(videoLink, youtubeId);
308+
const onPlayerReady: YouTubeProps["onReady"] = (event) => {
309+
// access to player in all event handlers via event.target
310+
event.target.pauseVideo();
311+
};
312+
313+
const opts: YouTubeProps["opts"] = {
314+
height: "200",
315+
width: "250",
316+
playerVars: {
317+
autoplay: 1,
318+
},
319+
};
320+
321+
return (
322+
<div className="mt-4 flex flex-col gap-5">
323+
<YouTube videoId={youtubeId} opts={opts} onPlayerReady={onPlayerReady} />
324+
</div>
325+
);
326+
}

frontend/app/map/_components/LocationCard.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export default function LocationCard({
114114
<div className="mb-4 flex items-center justify-between">
115115
<div className="w-64 text-sm font-bold">{locationinfo.title}</div>
116116
<div>
117-
{status === "authenticated" && (
117+
{status === "authenticated" ? (
118118
<div className="flex flex-col items-center">
119119
<FaHeart
120120
className={
@@ -125,6 +125,14 @@ export default function LocationCard({
125125
/>
126126
<p className="text-sm text-neutral-500">{favoriteCnt}</p>
127127
</div>
128+
) : (
129+
<div className="flex flex-col items-center">
130+
<FaHeart
131+
className="size-6 text-gray-500"
132+
onClick={handleFavoriteClick}
133+
/>
134+
<p className="text-sm text-neutral-500">{favoriteCnt}</p>
135+
</div>
128136
)}
129137
</div>
130138
</div>

0 commit comments

Comments
 (0)