@@ -109,7 +124,7 @@ export default function LoginPage() {
{loginError && (
-
+
{loginError}
)}
diff --git a/omechu-app/src/app/auth/reset-password/page.tsx b/omechu-app/src/app/auth/reset-password/page.tsx
new file mode 100644
index 000000000..aec3b3273
--- /dev/null
+++ b/omechu-app/src/app/auth/reset-password/page.tsx
@@ -0,0 +1,134 @@
+"use client";
+
+import { useState } from "react";
+import { useRouter } from "next/navigation";
+import Image from "next/image";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import {
+ resetPasswordSchema,
+ ResetPasswordFormValues,
+} from "@/lib/schemas/auth.schema";
+import Button from "@/app/components/auth/Button";
+import Input from "@/app/components/auth/Input";
+import AlertModal from "@/app/components/auth/AlertModal";
+
+export default function ResetPasswordPage() {
+ const [showPassword, setShowPassword] = useState(false);
+ const [showPasswordConfirm, setShowPasswordConfirm] = useState(false);
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const router = useRouter();
+
+ const {
+ register,
+ handleSubmit,
+ formState: { errors, isSubmitting },
+ } = useForm
({
+ resolver: zodResolver(resetPasswordSchema),
+ });
+
+ const onSubmit = async (data: ResetPasswordFormValues) => {
+ console.log(data);
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+ setIsModalOpen(true);
+ };
+
+ const handleModalConfirm = () => {
+ setIsModalOpen(false);
+ router.push("/auth/login");
+ };
+
+ return (
+ <>
+
+
+
+ 비밀번호 재설정
+
+
+ 사용하실 새로운 비밀번호를 설정해 주세요
+
+
+
+
+
+ {isModalOpen && (
+
+ )}
+ >
+ );
+}
diff --git a/omechu-app/src/app/auth/signup/page.tsx b/omechu-app/src/app/auth/signup/page.tsx
index ec041c0e4..f9491b2fc 100644
--- a/omechu-app/src/app/auth/signup/page.tsx
+++ b/omechu-app/src/app/auth/signup/page.tsx
@@ -5,11 +5,12 @@ import Image from "next/image";
import Button from "@/app/components/auth/Button";
import Input from "@/app/components/auth/Input";
import TermsModal from "@/app/components/auth/TermsModal";
-import PrivacyModal from "@/app/components/auth/PrivacyModal";
-import LocationModal from "@/app/components/auth/LocationModal";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { signupSchema, SignupFormValues } from "@/lib/schemas/auth.schema";
+import { termsForService } from "@/app/constant/terms/service";
+import { termsForPersonlInfo } from "@/app/constant/terms/personlInfo";
+import { termsForLocationlInfo } from "@/app/constant/terms/locationInfo";
export default function Signup() {
// const router = useRouter();
@@ -352,19 +353,34 @@ export default function Signup() {
{showTermsModal && (
setShowTermsModal(false)}
+ title="서비스 이용약관"
+ terms={termsForService}
+ onConfirm={() => {
+ setValue("termsService", true, { shouldValidate: true });
+ setShowTermsModal(false);
+ }}
onClose={() => setShowTermsModal(false)}
/>
)}
{showPrivacyModal && (
- setShowPrivacyModal(false)}
+ {
+ setValue("termsPrivacy", true, { shouldValidate: true });
+ setShowPrivacyModal(false);
+ }}
onClose={() => setShowPrivacyModal(false)}
/>
)}
{showLocationModal && (
- setShowLocationModal(false)}
+ {
+ setValue("termsLocation", true, { shouldValidate: true });
+ setShowLocationModal(false);
+ }}
onClose={() => setShowLocationModal(false)}
/>
)}
diff --git a/omechu-app/src/app/components/auth/AlertModal.tsx b/omechu-app/src/app/components/auth/AlertModal.tsx
new file mode 100644
index 000000000..290185e3f
--- /dev/null
+++ b/omechu-app/src/app/components/auth/AlertModal.tsx
@@ -0,0 +1,44 @@
+"use client";
+
+import Button from "./Button";
+import { MouseEvent } from "react";
+
+interface AlertModalProps {
+ title: string;
+ message: string;
+ onConfirm: () => void;
+}
+
+export default function AlertModal({
+ title,
+ message,
+ onConfirm,
+}: AlertModalProps) {
+ const handleWrapperClick = (e: MouseEvent) => {
+ if (e.target === e.currentTarget) {
+ onConfirm();
+ }
+ };
+
+ return (
+
+ );
+}
diff --git a/omechu-app/src/app/components/auth/Input.tsx b/omechu-app/src/app/components/auth/Input.tsx
index f0288ef11..6a7bec1f8 100644
--- a/omechu-app/src/app/components/auth/Input.tsx
+++ b/omechu-app/src/app/components/auth/Input.tsx
@@ -1,4 +1,4 @@
-import React, { forwardRef, useState } from "react";
+import React, { forwardRef } from "react";
type InputProps = {
label?: string;
@@ -8,21 +8,8 @@ type InputProps = {
const Input = forwardRef(
({ label, name, type, error, rightAddon, ...props }, ref) => {
- const [isPasswordVisible, setIsPasswordVisible] = useState(false);
- const isPasswordType = type === "password";
-
- const togglePasswordVisibility = () => {
- setIsPasswordVisible((prev) => !prev);
- };
-
- const inputType = isPasswordType
- ? isPasswordVisible
- ? "text"
- : "password"
- : type;
-
const baseStyle =
- "w-full h-10 px-4 border rounded-md focus:outline-none bg-white placeholder:text-[13px] placeholder:text-[#939393]";
+ "w-full h-10 px-4 border rounded-md focus:outline-none bg-white placeholder:text-[13px] placeholder:text-[#939393] text-black";
const normalStyle = "border-[#494949] focus:border-[#494949]";
const errorStyle = "border-red-500 focus:border-red-500";
const inputClassName = `${baseStyle} ${error ? errorStyle : normalStyle}`;
@@ -41,58 +28,13 @@ const Input = forwardRef(
-
- {isPasswordType ? (
-
- ) : (
- rightAddon
- )}
+
+ {rightAddon}
{error && {error}
}
diff --git a/omechu-app/src/app/components/auth/LocationModal.tsx b/omechu-app/src/app/components/auth/LocationModal.tsx
deleted file mode 100644
index 4e37ea2a4..000000000
--- a/omechu-app/src/app/components/auth/LocationModal.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import React from "react";
-import Image from "next/image";
-import Button from "./Button";
-
-type LocationModalProps = {
- onConfirm: () => void;
- onClose: () => void;
-};
-
-const LocationModal = ({ onConfirm, onClose }: LocationModalProps) => {
- const title = "위치기반 서비스 이용약관";
- const content = `1. 서비스 내용: 이용자의 현재 위치를 기반으로 주변 음식점 추천, 길찾기 등 위치기반 서비스를 제공합니다.
-2. 위치정보 수집 및 이용: 서비스 제공을 위해 이용자의 위치정보를 수집하며, 이는 이용자의 동의 하에 이루어집니다.
-3. 위치정보 보유 기간: 수집된 위치정보는 관련 법령에 따라 안전하게 보관되며, 목적 달성 시 파기됩니다.
-4. 권리: 이용자는 언제든지 위치정보 제공에 대한 동의를 철회할 수 있습니다.`;
-
- return (
-
-
-
-
{title}
-
-
-
- {content}
-
-
- 위의 내용을 모두 확인했으며 이에 동의합니다.
-
-
-
-
- );
-};
-
-export default LocationModal;
diff --git a/omechu-app/src/app/components/auth/LoginPromptModal.tsx b/omechu-app/src/app/components/auth/LoginPromptModal.tsx
index e46c03f7f..7e0c0ed51 100644
--- a/omechu-app/src/app/components/auth/LoginPromptModal.tsx
+++ b/omechu-app/src/app/components/auth/LoginPromptModal.tsx
@@ -26,16 +26,16 @@ const LoginPromptModal = ({ onConfirm, onClose }: LoginPromptModalProps) => {
-
더 쉽고 편한 추천을 원하시나요?
+
더 정교한 추천을 원하시나요?
- 로그인하고 더 다양한 서비스를 이용하세요!
+ 로그인 후 더 다양한 서비스를 누려보세요!
diff --git a/omechu-app/src/app/components/auth/PrivacyModal.tsx b/omechu-app/src/app/components/auth/PrivacyModal.tsx
deleted file mode 100644
index 1860ffd65..000000000
--- a/omechu-app/src/app/components/auth/PrivacyModal.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import React from "react";
-import Image from "next/image";
-import Button from "./Button";
-
-type PrivacyModalProps = {
- onConfirm: () => void;
- onClose: () => void;
-};
-
-const PrivacyModal = ({ onConfirm, onClose }: PrivacyModalProps) => {
- const title = "개인정보 처리방침";
- const content = `1. 수집하는 개인정보 항목: 이메일, 비밀번호, 서비스 이용 기록, 접속 로그
-2. 개인정보 수집 및 이용 목적: 회원제 서비스 제공, 본인 확인, 불량회원 관리, 서비스 개선
-3. 개인정보 보유 및 이용 기간: 회원 탈퇴 시까지. 단, 관계 법령에 따라 보존할 필요가 있는 경우 해당 기간까지 보관합니다.
-4. 개인정보의 제3자 제공: 법령에 근거한 경우를 제외하고, 이용자의 사전 동의 없이 개인정보를 제3자에게 제공하지 않습니다.`;
-
- return (
-
-
-
-
{title}
-
-
-
- {content}
-
-
- 위의 내용을 모두 확인했으며 이에 동의합니다.
-
-
-
-
- );
-};
-
-export default PrivacyModal;
diff --git a/omechu-app/src/app/components/auth/TermsModal.tsx b/omechu-app/src/app/components/auth/TermsModal.tsx
index c2ad748ad..60bf4e96f 100644
--- a/omechu-app/src/app/components/auth/TermsModal.tsx
+++ b/omechu-app/src/app/components/auth/TermsModal.tsx
@@ -1,30 +1,72 @@
-import React from "react";
+import React, { useRef } from "react";
import Image from "next/image";
import Button from "./Button";
+type Term = {
+ index: number | null;
+ about: string | null;
+ content: string;
+};
+
type TermsModalProps = {
+ title: string;
+ terms: Term[];
onConfirm: () => void;
onClose: () => void;
};
-const TermsModal = ({ onConfirm, onClose }: TermsModalProps) => {
- const title = "서비스 이용약관";
- const content = `1. 목적: 본 약관은 오메추가 제공하는 서비스의 이용과 관련하여 제반 권리, 의무 및 책임사항을 규정함을 목적으로 합니다.
-2. 이용자 정의: 이 약관에 동의하고 서비스를 이용하는 자를 '이용자'라 합니다.
-3. 서비스 제공: 오메추는 이용자에게 메뉴 추천, 식사 기록, 통계 제공 등 기능을 제공합니다.
-4. 이용자의 의무: 타인의 정보를 도용하거나 부정한 목적으로 서비스를 사용해서는 안됩니다. 서비스 내 제공된 콘텐츠를 무단으로 복제, 배포할 수 없습니다.`;
+const TermsModal = ({ title, terms, onConfirm, onClose }: TermsModalProps) => {
+ const contentRef = useRef
(null);
+
+ const scrollToTop = () => {
+ if (contentRef.current) {
+ contentRef.current.scrollTo({ top: 0, behavior: "smooth" });
+ }
+ };
return (
-
+
-
{title}
+ {title}
-
- {content}
+
+ {terms.map((item, key) => (
+
+ {item.index && item.about && (
+
+ 제 {item.index}조 ({item.about})
+
+ )}
+ {!item.index && !item.about && item.content === "부칙" && (
+ {item.content}
+ )}
+
+ {item.content}
+
+
+ ))}
+
+
+
위의 내용을 모두 확인했으며 이에 동의합니다.
diff --git a/omechu-app/src/app/components/onboarding/ProfileStep.tsx b/omechu-app/src/app/components/onboarding/ProfileStep.tsx
index a92b58885..dff52b42a 100644
--- a/omechu-app/src/app/components/onboarding/ProfileStep.tsx
+++ b/omechu-app/src/app/components/onboarding/ProfileStep.tsx
@@ -21,22 +21,32 @@ const ProfileStep = () => {
반가워요!
-
+
프로필을 입력해 주세요
-
-
+
+
-
+
diff --git a/omechu-app/src/app/onboarding/[step]/page.tsx b/omechu-app/src/app/onboarding/[step]/page.tsx
index 0aa3998b1..47515aa5e 100644
--- a/omechu-app/src/app/onboarding/[step]/page.tsx
+++ b/omechu-app/src/app/onboarding/[step]/page.tsx
@@ -114,44 +114,32 @@ export default function OnboardingPage() {
/>
-
+
{renderStepComponent()}
-