Skip to content

Commit

Permalink
Merge pull request #39 from youznn/main
Browse files Browse the repository at this point in the history
feature(Fe) - connect rest api
  • Loading branch information
youznn authored Dec 5, 2024
2 parents 4f4f5f5 + 67cfd05 commit 4d721ac
Show file tree
Hide file tree
Showing 27 changed files with 1,814 additions and 362 deletions.
2 changes: 1 addition & 1 deletion frontend/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function SignInPage() {
});

if (res && !res.error) {
console.log("Signed in: ", res);
//console.log("Signed in: ", res);
window.location.href = "/";
} else {
setError("Failed to sign in. Please check your credentials.");
Expand Down
15 changes: 9 additions & 6 deletions frontend/app/_components/CustomBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";

const borderColors = {
kpop: "border-violet-400",
drama: "border-yellow-400",
novel: "border-rose-400",
movie: "border-sky-400",
K_POP: "border-violet-400",
DRAMA: "border-yellow-400",
NOVEL: "border-rose-400",
MOVIE: "border-sky-400",
};

type categoryType = "kpop" | "drama" | "novel" | "movie";
type categoryType = "K_POP" | "DRAMA" | "NOVEL" | "MOVIE";

export default function CustomBadge({
title,
Expand All @@ -20,7 +20,10 @@ export default function CustomBadge({
return (
<Badge
variant="outline"
className={cn("h-6 rounded-3xl", borderColors[category])}
className={cn(
"h-6 overflow-hidden whitespace-nowrap rounded-3xl",
borderColors[category],
)}
>
{title}
</Badge>
Expand Down
85 changes: 74 additions & 11 deletions frontend/app/_components/NaverMap.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,93 @@
"use client";

import { useRef } from "react";
import {
Container as MapDiv,
NaverMap,
Marker,
useNavermaps,
} from "react-naver-maps";

function MyMap() {
// instead of window.naver.maps
type Category = "K_POP" | "DRAMA" | "MOVIE" | "NOVEL";
interface Location {
id: number;
title: string;
latitude: number;
longitude: number;
}

function MyMap({
locations,
category,
setCurrentLocationId,
}: {
locations: Location[];
category: Category;
setCurrentLocationId: (id: number) => void;
}) {
const navermaps = useNavermaps();

const makerImage = {
K_POP: "/icons/marker-1.png",
DRAMA: "/icons/marker-3.png",
MOVIE: "/icons/marker-4.png",
NOVEL: "/icons/marker-2.png",
};

const mapRef = useRef<InstanceType<typeof navermaps.Map> | null>(null);
return (
<NaverMap
defaultCenter={new navermaps.LatLng(37.3595704, 127.105399)}
defaultZoom={15}
>
<Marker defaultPosition={new navermaps.LatLng(37.3595704, 127.105399)} />
</NaverMap>
<MapDiv style={{ width: "100%", height: "350px" }}>
<NaverMap
defaultCenter={new navermaps.LatLng(36.4109466, 126.976882)}
defaultZoom={5}
ref={mapRef}
>
<>
{locations.map((location) => (
<Marker
key={location.id}
position={
new navermaps.LatLng(location.latitude, location.longitude)
}
icon={{
url: makerImage[category],
size: new navermaps.Size(25, 30),
scaledSize: new navermaps.Size(25, 30),
origin: new navermaps.Point(0, 0),
anchor: new navermaps.Point(16, 16),
}}
// marker 클릭 시 해당 위치로 이동
onClick={() => {
mapRef?.current?.setZoom(15);
mapRef?.current?.panTo(
new navermaps.LatLng(location.latitude, location.longitude),
);
setCurrentLocationId(location.id);
}}
/>
))}
</>
</NaverMap>
</MapDiv>
);
}

export default function SimpleMap() {
export default function MapWithMarker({
locations,
category,
setCurrentLocationId,
}: {
locations: Location[];
category: Category;
setCurrentLocationId: (id: number) => void;
}) {
return (
<MapDiv style={{ width: "100%", height: "300px" }}>
<MyMap />
<MapDiv style={{ width: "100%", height: "400px" }}>
<MyMap
locations={locations}
category={category}
setCurrentLocationId={setCurrentLocationId}
/>
</MapDiv>
);
}
130 changes: 101 additions & 29 deletions frontend/app/_components/PhotoUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,82 @@
import React, { useRef } from "react";
import { fetcherWithAuth } from "@/lib/utils";
import React, { useRef, useState } from "react";
import { MdAddToPhotos } from "react-icons/md";

const PhotoUploader = () => {
const PhotoUploader = ({ locationId }: { locationId?: number }) => {
const inputRef = useRef<HTMLInputElement | null>(null);
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);

const handleClick = () => {
inputRef.current?.click();
};

const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const files = event.target.files;
const gallery = document.getElementById("photoGallery");

if (gallery) gallery.innerHTML = ""; // 기존 사진 초기화

if (files) {
Array.from(files).forEach((file) => {
if (file.type.startsWith("image/")) {
const reader = new FileReader();
reader.onload = (e) => {
const img = document.createElement("img");
img.src = e.target?.result as string;
img.style.width = "150px";
img.style.margin = "10px";
img.style.borderRadius = "8px";
img.style.boxShadow = "0 4px 6px rgba(0, 0, 0, 0.1)";
if (gallery) gallery.appendChild(img);
};
reader.readAsDataURL(file);
}
const file = event.target.files?.[0];

if (file) {
setSelectedFile(file);
setIsModalOpen(true); // 파일을 선택하면 모달을 엽니다.
}
};

const handleUpload = async () => {
if (!selectedFile) {
alert("Please select a file to upload.");
return;
}

if (!locationId) {
alert("Please provide a location ID.");
return;
}

const formData = new FormData();

// ProofShotRequestDto를 JSON으로 변환하여 추가
const proofShotRequestDto = {
location_id: locationId,
description: ".",
};

try {
// JSON 데이터를 Blob으로 추가하면서 Content-Type을 명시합니다.
const proofShotBlob = new Blob([JSON.stringify(proofShotRequestDto)], {
type: "application/json",
});
formData.append("proof_shot", proofShotBlob);
formData.append("image", selectedFile);

const response = await fetcherWithAuth.post(
"api/v1/user/proof-shot/upload",
{
body: formData,
},
);

if (!response.ok) {
const errorText = await response.text();
//console.error("Server Response:", response.status, errorText);
throw new Error(
`Failed to upload photo: ${response.status} ${errorText}`,
);
}

const result = await response.json();
//console.log("Upload successful:", result);
alert("Upload successful!");
setIsModalOpen(false); // 업로드 성공 시 모달 닫기
} catch (error) {
console.error("Error uploading file:", error);
alert("Error uploading file. Please try again.");
}
};

const handleCloseModal = () => {
setIsModalOpen(false);
setSelectedFile(null);
};

return (
<div className="flex flex-col items-center">
{/* 클릭 트리거 */}
Expand All @@ -49,17 +93,45 @@ const PhotoUploader = () => {
ref={inputRef}
type="file"
accept="image/*"
name="proofshot"
multiple
className="hidden"
onChange={handleFileChange}
/>

{/* 갤러리 */}
<div
id="photoGallery"
className="mt-4 flex flex-wrap justify-center gap-4"
></div>
{/* 모달 */}
{isModalOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div className="w-[90%] max-w-md rounded-lg bg-white p-6 shadow-lg">
<h2 className="mb-4 text-lg font-semibold">Upload Photo</h2>
<div id="photoGallery" className="mb-4 flex justify-center">
{selectedFile && (
<img
src={URL.createObjectURL(selectedFile)}
alt="Selected preview"
style={{
width: "150px",
borderRadius: "8px",
boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
}}
/>
)}
</div>
<div className="flex justify-end gap-4">
<button
className="rounded-md bg-gray-300 px-4 py-2 text-gray-700 hover:bg-gray-400"
onClick={handleCloseModal}
>
Cancel
</button>
<button
className="rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
onClick={handleUpload}
>
Upload
</button>
</div>
</div>
</div>
)}
</div>
);
};
Expand Down
11 changes: 5 additions & 6 deletions frontend/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@ export default function RootLayout({
<html lang="en" className={`${pretendard.variable}`}>
<Script
type="text/javascript"
src={`https://oapi.map.naver.com/openapi/v3/maps.js?ncpClientId=${process.env.NEXT_PUBLIC_MAP_CLIENT_ID}&submodules=geocoder`}
src={`https://oapi.map.naver.com/openapi/v3/maps.js?ncpClientId=${process.env.NEXT_PUBLIC_MAP_CLIENT_ID}&submodules=geocoder&language=en`}
/>

<body
className={`${geistSans.variable} ${geistMono.variable} w-dvw px-8 py-5 antialiased`}
>
<AuthProvider>{children}</AuthProvider>
<body className={`${geistSans.variable} ${geistMono.variable} `}>
<div className="w-dvw bg-background px-8 py-5 antialiased">
<AuthProvider>{children}</AuthProvider>
</div>
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/map/[id]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div>
<BackButton />
<div className="px-10">{children}</div>
<div>{children}</div>
</div>
);
}
Loading

0 comments on commit 4d721ac

Please sign in to comment.