Skip to content

Commit

Permalink
[Feature] load mappin edit page (#34)
Browse files Browse the repository at this point in the history
* [chore]Update style guide with new grid and layout settings

* [feat] #21 로딩페이지 및 이벤트진입페이지 생성

* [fix] #21 수정 및 api 연결

* Delete fe/src/styles/globals.css

* [fix] #21 위치 아이콘 크기 수정

* [fix] #21 아이콘 크기 수정

* #26 비밀번호 확인 페이지 기능 추가

* [chore] styles.css 수정

* [style] load-mappin 스타일 및 동작 기능 수정

* #33 [feat] load mappin edit page

* 임시 커밋 - 병합 전 변경 사항 저장
  • Loading branch information
karnelll authored Oct 29, 2024
1 parent 31fb80b commit ae1f707
Show file tree
Hide file tree
Showing 24 changed files with 452 additions and 277 deletions.
2 changes: 1 addition & 1 deletion fe/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions fe/public/images/MMMM.svg

This file was deleted.

13 changes: 13 additions & 0 deletions fe/public/images/loadinglogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
14 changes: 7 additions & 7 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 @@ -36,13 +36,13 @@ function EventNameInput({
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 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 ae1f707

Please sign in to comment.