Skip to content

Commit

Permalink
#33 [feat] load mappin edit page
Browse files Browse the repository at this point in the history
  • Loading branch information
karnelll committed Oct 29, 2024
1 parent 23fa17a commit 319b6f1
Show file tree
Hide file tree
Showing 19 changed files with 390 additions and 103 deletions.
26 changes: 18 additions & 8 deletions fe/src/app/components/common/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
"use client";

import React from "react";
import { ButtonProps } from "@/types/types"; // 타입 import
import { ButtonProps } from "@/types/types";

// 함수 선언 방식으로 컴포넌트 정의
function Button({ label, onClick, type = "start", className }: ButtonProps) {
const buttonStyle =
type === "start"
? "bg-darkGray text-grayscale-0"
: "bg-gray-500 text-grayscale-0";
function Button({
label,
onClick,
type = "start",
className,
disabled = false,
}: ButtonProps) {
let buttonStyle = "bg-gray-200 text-gray-500 cursor-not-allowed";

if (!disabled) {
buttonStyle =
type === "start"
? "bg-darkGray text-white"
: "bg-gray-500 text-grayscale-0";
}

return (
<div className="w-full fixed bottom-[45px] left-0 right-0 flex justify-center">
<button
type="button" // type 속성 추가
type="button"
onClick={onClick}
className={`${buttonStyle} ${className} w-[328px] h-[60px] py-[17px] rounded-lg`}
disabled={disabled}
>
{label}
</button>
Expand Down
47 changes: 47 additions & 0 deletions fe/src/app/components/common/ExitModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";

interface ExitModalProps {
onCancel: () => void;
onExit: () => void;
}

function ExitModal({ onCancel, onExit }: ExitModalProps) {
return (
<div className="w-[272px] h-[202px] flex flex-col items-center inline-flex bg-gray-500 bg-opacity-50 rounded-lg">
<div className="w-full h-[148px] px-[39px] pt-9 pb-7 bg-white rounded-tl-xl rounded-tr-xl flex flex-col items-center gap-2.5">
<div className="w-full h-[84px] flex flex-col items-center gap-2">
<div className="w-full text-center text-[#1d1d1d] text-xl font-semibold font-['Pretendard'] leading-7">
저장하지 않고 나갈까요?
</div>
<div className="text-center text-[#8e8e8e] text-base font-medium font-['Pretendard'] leading-normal">
이대로 나가면
<br /> 작성하던 내용이 사라져요
</div>
</div>
</div>

<div className="w-full flex">
<button
type="button"
onClick={onCancel}
className="w-1/2 h-[54px] bg-[#f0f0f0] rounded-bl-xl flex items-center justify-center"
>
<span className="text-center text-[#2c2c2c] text-lg font-medium font-['Pretendard'] leading-relaxed">
취소
</span>
</button>

<button
type="button"
onClick={onExit}
className="w-1/2 h-[54px] bg-[#1d1d1d] rounded-br-xl flex items-center justify-center"
>
<span className="text-center text-white text-lg font-medium font-['Pretendard'] leading-relaxed">
나가기
</span>
</button>
</div>
</div>
);
}
export default ExitModal;
1 change: 0 additions & 1 deletion fe/src/app/components/common/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ function Navigation({ showBackButton = true }: NavigationProps) {
<header className="nav-bar sticky top-[36px] z-10">
{showBackButton && (
<div className="absolute left-0">
{/* 왼쪽 간격을 0으로 설정 */}
<button type="button" onClick={handleBackClick} className="p-2">
<Image
src="/images/ArrowBack.svg"
Expand Down
17 changes: 8 additions & 9 deletions fe/src/app/eventcreate-page/components/EventNameInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ function EventNameInput({
}: EventNameInputProps) {
const [eventName, setEventName] = useState("");
const [isFocused, setIsFocused] = useState(false);
const [hasUserEdited, setHasUserEdited] = useState(false); // 사용자가 직접 수정했는지 확인
const [isLoading, setIsLoading] = useState(true); // 로딩 상태 추가
const [hasUserEdited, setHasUserEdited] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const currentDate = getCurrentDate();

useEffect(() => {
Expand All @@ -30,19 +30,19 @@ function EventNameInput({
setEventName(newEventName);
onChange(newEventName);
}
setIsLoading(false); // 로딩 완료 상태로 변경
setIsLoading(false);
}, [selectedLocation, currentDate, onChange, hasUserEdited]);

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
setEventName(newValue);
setHasUserEdited(true); // 사용자가 수동으로 입력하면 플래그를 설정
setHasUserEdited(true);
onChange(newValue);
};

const handleClear = () => {
setEventName("");
setHasUserEdited(true); // 수동으로 입력이 변경되었음을 알림
setHasUserEdited(true);
onChange("");
};

Expand All @@ -54,7 +54,7 @@ function EventNameInput({
: "text-text-default";

const charCount = eventName.length;
const showWarning = charCount < 1 || charCount > 20; // 글자 수 검사 조건 설정
const showWarning = charCount < 1 || charCount > 20;
const isDefaultValue =
eventName === `${currentDate} 모임` ||
eventName === `${currentDate} ${selectedLocation} 모임`;
Expand All @@ -81,8 +81,8 @@ function EventNameInput({

{eventName && !isDefaultValue && (
<div
role="button" // 상호작용 요소로 설정
tabIndex={0} // 키보드로 접근 가능
role="button"
tabIndex={0}
onClick={handleClear}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") handleClear();
Expand All @@ -99,7 +99,6 @@ function EventNameInput({
)}
</div>

{/* 로딩 중이 아닐 때 글자 수 검사 결과 표시 */}
{!isLoading && (
<>
{showWarning ? (
Expand Down
13 changes: 6 additions & 7 deletions fe/src/app/eventcreate-page/components/LocationInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function LocationInput({ className, onSelect }: LocationInputProps) {
const data = await response.json();

if (data.places && data.places.length > 0) {
setResults(data.places); // 결과 저장
setResults(data.places);
} else {
alert("현재 위치에 대한 장소를 찾을 수 없습니다.");
}
Expand All @@ -54,7 +54,7 @@ function LocationInput({ className, onSelect }: LocationInputProps) {

const data = await response.json();
if (data.code === 200) {
setResults(data.data); // 검색 결과 저장
setResults(data.data);
} else {
setResults([]);
alert(`장소 검색에 실패했습니다: ${data.message}`);
Expand All @@ -70,16 +70,16 @@ function LocationInput({ className, onSelect }: LocationInputProps) {
setLocation(value);

if (value.length > 0) {
fetchPlacesBySearch(value); // 검색 실행
fetchPlacesBySearch(value);
} else {
setResults([]); // 입력이 없으면 결과 초기화
setResults([]);
}
};

const handleSelectPlace = ({ name }: { name: string }) => {
setLocation(name);
setResults([]);
onSelect(name); // 부모 컴포넌트에 선택된 장소 전달
onSelect(name);
};

const handleCurrentLocation = async () => {
Expand All @@ -91,7 +91,7 @@ function LocationInput({ className, onSelect }: LocationInputProps) {
navigator.geolocation.getCurrentPosition(
async ({ coords }) => {
const { latitude, longitude } = coords;
await fetchPlaces(latitude.toString(), longitude.toString()); // 현재 위치를 이용해 장소 검색
await fetchPlaces(latitude.toString(), longitude.toString());
},
() => {
alert("위치 정보를 가져오는 중 오류가 발생했습니다.");
Expand Down Expand Up @@ -122,7 +122,6 @@ function LocationInput({ className, onSelect }: LocationInputProps) {
/>
</div>

{/* 현재 위치 찾기 버튼 복원 */}
<div
role="button"
tabIndex={0}
Expand Down
29 changes: 14 additions & 15 deletions fe/src/app/eventcreate-page/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useLocationStore } from "@/app/eventcreate-page/stores/useLocationStore";
import Navigation from "@/app/components/common/Navigation";
Expand All @@ -11,9 +11,16 @@ import Button from "@/app/components/common/Button";
function EventCreatePage() {
const [selectedLocation, setSelectedLocation] = useState("");
const [eventName, setEventName] = useState("");
const [isFormComplete, setIsFormComplete] = useState(false);
const { moveToLocation } = useLocationStore();
const router = useRouter();

useEffect(() => {
setIsFormComplete(
selectedLocation.trim() !== "" && eventName.trim() !== ""
);
}, [selectedLocation, eventName]);

const handleLocationSelect = (location: string) => {
setSelectedLocation(location);
};
Expand All @@ -23,26 +30,17 @@ function EventCreatePage() {
};

const handleNextClick = () => {
if (!isFormComplete) return;

const latitude = 37.5665;
const longitude = 126.978;

if (!eventName) {
alert("이벤트 이름을 입력해주세요.");
return;
}

if (!selectedLocation) {
alert("장소를 선택해주세요.");
return;
}

moveToLocation(latitude, longitude);

router.push("/map-page");
};

return (
<div className="w-full h-screen relative bg-white mx-auto flex flex-col justify-center items-center">
<div className="w-[360px] h-screen relative bg-white mx-auto flex flex-col">
<div className="sticky top-0 w-full z-10">
<Navigation title="이벤트 생성" showBackButton />
</div>
Expand All @@ -64,9 +62,10 @@ function EventCreatePage() {
<div className="w-full flex justify-center mb-[45px]">
<Button
label="다음"
type="next"
type="start"
onClick={handleNextClick}
className="w-[328px] h-[60px] py-[17px] rounded-lg bg-black text-white"
className="w-[328px] h-[60px] py-[17px] rounded-lg"
disabled={!isFormComplete}
/>
</div>
</div>
Expand Down
67 changes: 67 additions & 0 deletions fe/src/app/load-mappin-edit/components/Form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"use client";

import React, { useState, useEffect, FormEvent } from "react";
import LinkField from "./LinkField";

interface FormProps {
userName: string;
}

export default function Form({ userName }: FormProps) {
const [mapLinks, setMapLinks] = useState([""]);
const [storeLinks, setStoreLinks] = useState([""]);
const [isTooltipVisible, setIsTooltipVisible] = useState(true);
const [isFormComplete, setIsFormComplete] = useState(false); // isFormComplete 추가

// mapLinks와 storeLinks가 모두 입력되었을 때만 isFormComplete를 true로 설정
useEffect(() => {
setIsFormComplete(
mapLinks.some((link) => link.trim() !== "") &&
storeLinks.some((link) => link.trim() !== "")
);
}, [mapLinks, storeLinks]);

const handleSubmit = (e: FormEvent) => {
e.preventDefault();
const formData = {
userName,
mapLinks,
storeLinks,
};
console.log("폼 데이터:", formData);
};

return (
<div className="px-4">
<form onSubmit={handleSubmit}>
<LinkField
label="맵핀 모음 링크"
placeholder="링크 붙여넣기"
value={mapLinks}
onChange={setMapLinks}
showTooltip={isTooltipVisible}
onInfoClick={() => setIsTooltipVisible(true)}
/>

<LinkField
label="가게 정보 링크"
placeholder="링크 붙여넣기"
value={storeLinks}
onChange={setStoreLinks}
/>

<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"
}`}
type="submit"
disabled={!isFormComplete}
>
확인
</button>
</form>
</div>
);
}
Loading

0 comments on commit 319b6f1

Please sign in to comment.