Skip to content

Commit

Permalink
Merge branch 'main' into feature/detail-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
karnelll authored Oct 31, 2024
2 parents 546751c + 7562a49 commit dba6d81
Show file tree
Hide file tree
Showing 13 changed files with 311 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React, { useRef, useState, useEffect, useCallback } from "react";
import { useRouter, useParams } from "next/navigation";
import { v4 as uuidv4 } from "uuid";
import { useUserDataStore } from "../stores/useUserDataStore"; // zustand store import

export default function PasswordInput() {
const [password, setPassword] = useState(["", "", "", ""]);
Expand All @@ -11,8 +12,8 @@ export default function PasswordInput() {
const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
const router = useRouter();
const { id, nonMemberId } = useParams();
const setUserData = useUserDataStore((state) => state.setUserData); // Use zustand's setUserData

// Define submitPassword before useEffect
const submitPassword = useCallback(async () => {
const fullPassword = password.join("");

Expand All @@ -38,6 +39,16 @@ export default function PasswordInput() {
);

if (response.ok) {
const data = await response.json(); // Get the JSON response

// Save data in zustand store
setUserData({
nonMemberId: data.nonMemberId,
name: data.name,
bookmarkUrls: data.bookmarkUrls || [],
storeUrls: data.storeUrls || [],
});

router.push(`/event-maps/${id}/${nonMemberId}/load-mappin-edit`);
} else {
setHasError(true);
Expand All @@ -47,7 +58,7 @@ export default function PasswordInput() {
} catch (error) {
setHasError(true);
}
}, [id, nonMemberId, password, router]);
}, [id, nonMemberId, password, router, setUserData]);

useEffect(() => {
if (password.every((digit) => digit !== "")) {
Expand Down Expand Up @@ -98,7 +109,7 @@ export default function PasswordInput() {
<div className="inline-flex items-center justify-start gap-4 mb-4">
{password.map((_, i) => (
<div
key={uuidv4()} // Unique key for each render
key={uuidv4()}
className={`w-14 h-14 p-4 bg-[#f7f7f7] rounded-lg inline-flex items-center ${
hasError ? "border-2 border-primary-50" : ""
} ${currentIndex === i ? "border-2 border-gray-950" : ""}`}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,65 @@
"use client";

import React, { useState, useEffect, FormEvent } from "react";
import { useRouter, useParams } from "next/navigation";
import LinkField from "./LinkField";
import { useUserDataStore } from "../../stores/useUserDataStore";

interface FormProps {
userName: string;
}

export default function Form({ userName }: FormProps) {
const [mapLinks, setMapLinks] = useState([""]);
const [storeLinks, setStoreLinks] = useState([""]);
export default function Form() {
const { userData } = useUserDataStore(); // Access userData from zustand
const [mapLinks, setMapLinks] = useState<string[]>([]);
const [storeLinks, setStoreLinks] = useState<string[]>([]);
const [isTooltipVisible, setIsTooltipVisible] = useState(true);
const [isFormComplete, setIsFormComplete] = useState(false); // isFormComplete 추가
const router = useRouter();
const { id } = useParams(); // Retrieve `id` from the route parameters

// mapLinks와 storeLinks가 모두 입력되었을 때만 isFormComplete를 true로 설정
// Load mapLinks and storeLinks from the store when the component mounts
useEffect(() => {
setIsFormComplete(
mapLinks.some((link) => link.trim() !== "") &&
storeLinks.some((link) => link.trim() !== "")
);
}, [mapLinks, storeLinks]);
if (userData) {
setMapLinks(
userData.bookmarkUrls?.filter((link) => link.trim() !== "") || []
);
setStoreLinks(
userData.storeUrls?.filter((link) => link.trim() !== "") || []
);
}
}, [userData]);

const handleSubmit = (e: FormEvent) => {
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();

// Filter out any empty strings just before submitting
const filteredMapLinks = mapLinks.filter((link) => link.trim() !== "");
const filteredStoreLinks = storeLinks.filter((link) => link.trim() !== "");

const formData = {
userName,
mapLinks,
storeLinks,
nonMemberId: userData?.nonMemberId, // Assuming nonMemberId is available in userData
bookmarkUrls: filteredMapLinks,
storeUrls: filteredStoreLinks,
};
console.log("폼 데이터:", formData);

try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/nonmembers/pings`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(formData),
}
);

if (response.ok) {
console.log("데이터가 성공적으로 전송되었습니다.");
router.push(`/event-maps/${id}`); // Redirect to the specified route on success
} else {
console.error("데이터 전송 실패:", response.status);
}
} catch (error) {
console.error("서버 오류 발생:", error);
}
};

return (
Expand All @@ -38,7 +69,9 @@ export default function Form({ userName }: FormProps) {
label="맵핀 모음 링크"
placeholder="링크 붙여넣기"
value={mapLinks}
onChange={setMapLinks}
onChange={(links) =>
setMapLinks(links.filter((link) => link.trim() !== ""))
}
showTooltip={isTooltipVisible}
onInfoClick={() => setIsTooltipVisible(true)}
/>
Expand All @@ -47,17 +80,14 @@ export default function Form({ userName }: FormProps) {
label="가게 정보 링크"
placeholder="링크 붙여넣기"
value={storeLinks}
onChange={setStoreLinks}
onChange={(links) =>
setStoreLinks(links.filter((link) => link.trim() !== ""))
}
/>

<button
className={`w-full flex items-center text-lg font-200 justify-center h-[60px] rounded-small ${
isFormComplete
? "bg-grayscale-90 text-white"
: "bg-grayscale-20 text-mediumGray"
}`}
className="w-full flex items-center text-lg font-200 justify-center h-[60px] rounded-small bg-grayscale-90 text-white "
type="submit"
disabled={!isFormComplete}
>
확인
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React, { useState } from "react";
"use client";

import React, { useState, useEffect } from "react";
import { nanoid } from "nanoid";
import Image from "next/image";
import { useUserDataStore } from "../../stores/useUserDataStore";

interface LinkFieldProps {
label: string; // label 속성 추가
label: string;
placeholder: string;
value: string[];
onChange: (value: string[]) => void;
Expand All @@ -19,31 +22,62 @@ export default function LinkField({
showTooltip = true,
onInfoClick,
}: LinkFieldProps) {
const userData = useUserDataStore((state) => state.userData);
const [inputFields, setInputFields] = useState(
value.map((val) => ({ id: nanoid(), text: val }))
value.length > 0
? value.map((val) => ({ id: nanoid(), text: val }))
: [{ id: nanoid(), text: "" }]
);

useEffect(() => {
const initialData =
label === "맵핀 모음 링크" ? userData.bookmarkUrls : userData.storeUrls;
setInputFields(
initialData.length > 0
? initialData.map((val) => ({ id: nanoid(), text: val }))
: [{ id: nanoid(), text: "" }]
);
}, [label, userData]);

useEffect(() => {
if (inputFields.length === 0) {
setInputFields([{ id: nanoid(), text: "" }]);
}
}, [inputFields]);

const handleInputChange = (id: string, inputValue: string) => {
const newInputs = inputFields.map((field) =>
field.id === id ? { ...field, text: inputValue } : field
);
setInputFields(newInputs);
onChange(newInputs.map((field) => field.text));
onChange(
newInputs.map((field) => field.text).filter((text) => text.trim() !== "")
);
};

const clearInput = (id: string) => {
const newInputs = inputFields.map((field) =>
field.id === id ? { ...field, text: "" } : field
);
setInputFields(newInputs);
onChange(newInputs.map((field) => field.text));
onChange(
newInputs.map((field) => field.text).filter((text) => text.trim() !== "")
);
};

const addInputField = () => {
const newField = { id: nanoid(), text: "" };
const updatedInputs = [...inputFields, newField];
setInputFields(updatedInputs);
onChange(updatedInputs.map((field) => field.text));
onChange(
updatedInputs
.map((field) => field.text)
.filter((text) => text.trim() !== "")
);
};

const handleNaverMove = () => {
window.open("https://m.place.naver.com/my/place");
};

return (
Expand All @@ -67,15 +101,28 @@ export default function LinkField({
/>
{showTooltip && (
<div
className="absolute left-1/2 -translate-x-[51%] bottom-full mb-2 bg-black text-white text-caption rounded px-[12px] py-[10px] w-[215px]"
className="absolute left-1/2 -translate-x-[48.9%] bottom-full mb-2 bg-black text-white text-caption rounded px-[12px] py-[10px] w-[215px]"
aria-hidden={!showTooltip}
>
즐겨찾기 링크 복사 방법을 확인해보세요
<div className="absolute left-1/2 bottom-[-6px] -translate-x-1/2 w-0 h-0 border-l-[6px] border-l-transparent border-r-[6px] border-r-transparent border-t-[6px] border-t-black" />
<div className="absolute left-1/2 bottom-[-4px] -translate-x-1/2 w-0 h-0 border-l-[6px] border-l-transparent border-r-[6px] border-r-transparent border-t-[6px] border-t-black" />
</div>
)}
</div>
)}
<button
type="button"
className="mr-0 ml-auto text-grayscale-50 flex items-center text-text-sm1"
onClick={handleNaverMove}
>
네이버 지도
<Image
src="/svg/rightArrow.svg"
alt="rightArrow"
width={12}
height={24}
/>
</button>
</label>
<div className="flex flex-col items-center border-grayscale-10 border p-[16px] gap-[16px] rounded-medium">
{inputFields.map((field) => (
Expand All @@ -85,7 +132,7 @@ export default function LinkField({
value={field.text}
onChange={(e) => handleInputChange(field.id, e.target.value)}
placeholder={placeholder}
className="w-full p-3 bg-gray-50 rounded-md focus:outline-none focus:ring-2 focus:ring-grayscale-80"
className="w-full p-3 pr-10 bg-gray-50 rounded-md focus:outline-none focus:ring-2 focus:ring-grayscale-80"
style={{
border: "none",
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import Image from "next/image";
import { useRouter, useParams } from "next/navigation";
import ExitModal from "@/app/event-maps/[id]/[nonMemberId]/components/PinExitModal";
import Form from "./components/Form";
import { useUserDataStore } from "../stores/useUserDataStore";

export default function Page() {
const [userName] = useState("규리");
const userName = useUserDataStore((state) => state.userData.name);

const [isModalOpen, setIsModalOpen] = useState(false);
const router = useRouter();
const { id } = useParams();
Expand Down Expand Up @@ -46,7 +48,7 @@ export default function Page() {
{userName}님의 맵핀 모음이에요
</div>
)}
<Form userName={userName} />
<Form />
<div className="h-[20px]" />

{isModalOpen && (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { create } from "zustand";

interface UserData {
nonMemberId: number | null;
name: string;
bookmarkUrls: string[];
storeUrls: string[];
}

interface UserDataStore {
userData: UserData;
setUserData: (data: UserData) => void;
}

export const useUserDataStore = create<UserDataStore>((set) => ({
userData: {
nonMemberId: null,
name: "",
bookmarkUrls: [],
storeUrls: [],
},
setUserData: (data) => set({ userData: data }),
}));
Loading

0 comments on commit dba6d81

Please sign in to comment.