Skip to content
Open
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
d048029
feat: text token 생성
hongggyelim Apr 21, 2025
736b653
refactor: text 토큰 적용
hongggyelim Apr 21, 2025
ac28230
fix: 스토리북에서 select 열기 위한 제어 추가
hongggyelim Apr 21, 2025
d8630a4
chore: styles 배럴파일 수정
hongggyelim Apr 21, 2025
3c919ce
refactor: apps/user text token 적용
hongggyelim Apr 21, 2025
f6f8fe0
chore: minor 버전 업데이트
hongggyelim Apr 21, 2025
fc6b159
feat: 정보 수정 페이지 작성
hongggyelim Apr 22, 2025
c16ea38
fix: select 너비 prop 내부 textinput에 전달
hongggyelim Apr 22, 2025
40f2919
feat: 정보수정 - 필수입력 페이지 작업
hongggyelim Apr 22, 2025
4329947
feat: small bold 추가
hongggyelim Apr 22, 2025
dc1485a
Merge branch 'design/text-token' into feat/mypage
hongggyelim Apr 22, 2025
952c344
feat: 필드 타입, 에러 정의
hongggyelim Apr 22, 2025
0243889
feat : 필수 입력 폼
hongggyelim Apr 23, 2025
6e18ece
fix: select disabled 기본값 추가 - hover 스타일 작동
hongggyelim Apr 23, 2025
205ff9d
fix : 배경 호버 시 버튼에도 호버 스타일 적용
hongggyelim Apr 23, 2025
649ec47
refactor : 파일 업로드 상위에서 관리하도록 수정
hongggyelim Apr 23, 2025
a9f2ca9
refactor: File 형태로 상위로 전달
hongggyelim Apr 23, 2025
8494192
feat: 마이페이지 필수 폼 완료
hongggyelim Apr 23, 2025
0ef2c48
chore: disabled 기본값 추가
hongggyelim Apr 23, 2025
ea249c7
feat: 선택 입력 폼 작성
hongggyelim Apr 23, 2025
3d0ff42
feat: 회원정보 폼 작성
hongggyelim Apr 23, 2025
1b4084f
chore: layout 제거
hongggyelim Apr 23, 2025
7fa46a9
fix: changeset root에서 진행
hongggyelim Apr 23, 2025
17aebca
version : minor bump
hongggyelim Apr 23, 2025
0a36be1
Merge branch 'design/text-token' into feat/mypage
hongggyelim Apr 23, 2025
93867c6
Merge remote-tracking branch 'origin/feature' into feat/mypage
hongggyelim Apr 24, 2025
119c7f6
chore: svg 수정
hongggyelim Apr 24, 2025
1b964fb
fix : PR 리뷰 반영
hongggyelim Apr 25, 2025
be473f3
feat: 이미지 삭제 시 File onChange
hongggyelim Apr 25, 2025
0aff4cb
Merge remote-tracking branch 'origin/feature' into feat/mypage
hongggyelim Apr 25, 2025
0ec7573
chore : 파일 최대 개수 제한 로직 중복내용 수정
hongggyelim Apr 25, 2025
fb78f3b
fix: watch를 getValues로 대체
hongggyelim Apr 25, 2025
4576010
chore: 키 정규식으로 변경
hongggyelim Apr 25, 2025
b4fa25a
chore: line height 수정 및 변수 춝
hongggyelim Apr 29, 2025
d360a7f
chore: toast 색상 토큰 추가
hongggyelim Apr 29, 2025
c8c35a2
chore: 색상 token 반영
hongggyelim Apr 29, 2025
101b078
Merge branch 'revise/token' into feat/mypage
hongggyelim Apr 29, 2025
8ab61ad
chore: text area 에러메시지 자리 차지 제거
hongggyelim Apr 29, 2025
29e8d83
chore: 마이페이지 ui 변경사항 반영
hongggyelim Apr 29, 2025
5f9af57
fix: optional chain 으로 수정
hongggyelim Apr 29, 2025
8b60623
feat: 이미지 드래그앤드롭 기능 추가
hongggyelim Apr 29, 2025
059bfd9
chore: 글씨 색상 변경
hongggyelim Apr 29, 2025
1f58d1f
feat: tool tip 구현
hongggyelim Apr 29, 2025
48916f1
chore: text 0 기본값 추가, 이미지 있을때 툴팁 보여줌
hongggyelim Apr 30, 2025
9716161
feat: 닉네임 필드 추가
hongggyelim Apr 30, 2025
0b73ce8
chore: 로그인 밑줄 추가
hongggyelim Apr 30, 2025
5575950
chore: css 수정
hongggyelim May 1, 2025
e575636
Merge remote-tracking branch 'origin/feature' into feat/mypage
hongggyelim Jul 26, 2025
9c51a5c
fix: 메뉴 선택시 드롭다운 닫히도록 수정
hongggyelim Aug 16, 2025
f8564a2
fix: header 드롭다운 메뉴 가려지는 이슈 해결을 위해 portal 적용
hongggyelim Aug 16, 2025
e8eb330
fix: return 밖 JSX을 조건부 렌더링으로 수정
hongggyelim Aug 16, 2025
ff99c97
Merge remote-tracking branch 'origin/feature' into feat/mypage
hongggyelim Aug 31, 2025
744c2ec
feat: 비밀번호 변경 모달 추가
hongggyelim Oct 1, 2025
593a5c4
rename : ui component file
hongggyelim Nov 24, 2025
140c454
modify : 디렉토리 아키텍쳐 수정
hongggyelim Nov 24, 2025
8277598
modify : ROUTES enum 추가
hongggyelim Nov 24, 2025
9a23f85
modify : portal 컴포넌트 적용
hongggyelim Dec 25, 2025
750b7da
modify: 변수명 컨벤션 수정
hongggyelim Dec 25, 2025
5dcc926
modify : add dialog size prop & use useWatch instead watch
hongggyelim Dec 25, 2025
0e29be6
rename some components
hongggyelim Dec 25, 2025
26c39d3
docs: typography mdx 추가
hongggyelim Dec 25, 2025
ced30bc
fix: font smooth 추가
hongggyelim Dec 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fluffy-candies-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@date-project/user": minor
---

modify mypage
1 change: 1 addition & 0 deletions apps/user/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"check-types": "tsc --noEmit"
},
"dependencies": {
"@hello-pangea/dnd": "^18.0.1",
"@vanilla-extract/css": "^1.17.1",
"@vanilla-extract/css-utils": "^0.1.4",
"@vanilla-extract/recipes": "^0.5.5",
Expand Down
3 changes: 2 additions & 1 deletion apps/user/src/app/(auth)/_styles/style.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ export const loginText = style([

export const loginLink = style([
{
color: Color.accent.default,
color: ColorVar.blue.light[8],
textDecoration: "underline",
},
textSprinkles({ text: "smallBold" }),
]);
2 changes: 1 addition & 1 deletion apps/user/src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function AuthLayout({
const pathName = usePathname();
const isLoginPage = pathName.includes("login");
return (
<main className={bg}>
<main className={bg} id="main">
<div className={contentWrapper({ isLoginPage })}>{children}</div>
</main>
);
Expand Down
15 changes: 6 additions & 9 deletions apps/user/src/app/mypage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
"use client";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import type { ReactNode } from "react";
import AccountStage from "../../shared/components/myPage/stages/AccountStage";
import OptionalStage from "../../shared/components/myPage/stages/OptionalStage";
import RequiredStage from "../../shared/components/myPage/stages/RequiredStage";
import AccountStage from "../../shared/components/myPage/Stages/AccountStage";
import OptionalStage from "../../shared/components/myPage/Stages/OptionalStage";
import RequiredStage from "../../shared/components/myPage/Stages/RequiredStage";
import {
description,
layoutMain,
Expand All @@ -24,26 +23,22 @@ export default function MyPageStage() {
param: Stage;
menu: string;
description: string;
component: ReactNode;
}[] = [
{
param: "required",
menu: "필수 입력",
description: "필수 정보를 모두 입력하시면 프로필이 공개됩니다.",
component: <RequiredStage />,
},
{
param: "optional",
menu: "선택 입력",
description: "추가 정보를 입력하시면 매칭 확률이 높아집니다.",
component: <OptionalStage />,
},
{
param: "account",
menu: "회원 정보",
description:
"일부 항목은 관리자 승인 후 수정이 가능합니다. 변경이 필요한 경우 문의해주세요.",
component: <AccountStage />,
},
];

Expand All @@ -70,7 +65,9 @@ export default function MyPageStage() {
</li>
))}
</ul>
{tabInfo.find((item) => item.param === stage)?.component}
{stage === "required" && <RequiredStage />}
{stage === "optional" && <OptionalStage />}
{stage === "account" && <AccountStage />}
</div>
</section>
</main>
Expand Down
33 changes: 21 additions & 12 deletions apps/user/src/shared/components/layouts/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import UserIcon from "@date-project/user/public/userIcon.svg";
import { Button } from "@repo/ui";
import Link from "next/link";
import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import useUserStore from "../../../stores/useUserStore";
import type { ListType } from "./listType";
import ProfileMenu from "./ProfileMenu";
Expand All @@ -17,7 +18,9 @@ import {
userProfile,
} from "./style.css";
const Header = () => {
const [isOpen, setIsOpen] = useState(false);
const [isOpenDropdown, setIsOpenDropdown] = useState(false);
const [headerDOM, setHeaderDOM] = useState<HTMLElement | null>(null);

const { user, setLogout } = useUserStore();

const menuRef = useRef<HTMLDivElement | null>(null);
Expand All @@ -38,16 +41,19 @@ const Header = () => {
menuRef.current &&
!menuRef.current.contains(e.target as HTMLElement)
) {
setIsOpen(false);
setIsOpenDropdown(false);
}
};

document.addEventListener("click", handleClickOutside);
return () => {
document.removeEventListener("click", handleClickOutside);
};
}, [isOpen]);
}, [isOpenDropdown]);

useEffect(() => {
setHeaderDOM(document.getElementById("main"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apps/user/src/app/(auth)/layout.tsx가 적용되는 페이지가 login, signup인데 header를 쓰지않는 페이지인데,
왜 여기에 state값을 저장하려는건지 궁금함

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 DOM을 가져오는건 지양하고 ref를 활용했으면 함

}, []);
return (
<header className={header}>
<div className={logoWrapper}>
Expand All @@ -66,18 +72,21 @@ const Header = () => {
<button
className={userProfile}
type="button"
onClick={() => setIsOpen((prev) => !prev)}
onClick={() => setIsOpenDropdown((prev) => !prev)}
>
<UserIcon className={userIcon} alt="user" />
</button>
{isOpen && (
<ProfileMenu
name="홍길동" // 유저 정보 넘겨주기
tel="010-1234-5678" // 대시 추가해서 string으로 넘겨주기
list={profileMenuList}
ref={menuRef}
/>
)}
{isOpenDropdown &&
createPortal(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Portal 컴포넌트를 만들었으니깐 만든걸 활용

<ProfileMenu
name="홍길동" // 유저 정보 넘겨주기
tel="010-1234-5678" // 대시 추가해서 string으로 넘겨주기
list={profileMenuList}
ref={menuRef}
onClose={() => setIsOpenDropdown(false)}
/>,
headerDOM || document.body,
)}
</>
) : (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ type MenuProps = {
tel: string;
list?: ListType[];
ref: Ref<HTMLDivElement>;
onClose: () => void;
};

const ProfileMenu = ({ name, tel, list = [], ref }: MenuProps) => {
const ProfileMenu = ({ name, tel, list = [], ref, onClose }: MenuProps) => {
return (
<div className={menuWrapper} ref={ref}>
<div className={infoWrapper}>
Expand All @@ -35,7 +36,7 @@ const ProfileMenu = ({ name, tel, list = [], ref }: MenuProps) => {
</div>
<ul className={listWrapper}>
{list.map((item: ListType) => (
<li key={item.title} className={listItem}>
<li key={item.title} className={listItem} onClick={onClose}>
{item.href && <Link href={item.href}>{item.title}</Link>}
{item.action && (
<button type="button" onClick={item.action}>
Expand Down
12 changes: 7 additions & 5 deletions apps/user/src/shared/components/layouts/header/style.css.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Color, textSprinkles } from "@repo/ui";
import { Color, textSprinkles, Zindex } from "@repo/ui";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 왜 zIndex가 아니라 Zindex로 이상하게 되었지

import { style } from "@vanilla-extract/css";
import { calc } from "@vanilla-extract/css-utils";

export const header = style({
position: "fixed",
Expand Down Expand Up @@ -69,15 +68,18 @@ export const relative = style({
});
// ---- ProfileMenu ----
export const menuWrapper = style({
position: "absolute",
right: 0,
top: calc.add("100%", "28px").toString(),
position: "fixed",
top: "80px",
right: "32px",

display: "flex",
flexDirection: "column",

width: "200px",
borderRadius: "8px",
backgroundColor: Color.secondary.default,

zIndex: Zindex.dropdown,
});

export const infoWrapper = style({
Expand Down
17 changes: 16 additions & 1 deletion apps/user/src/shared/components/myPage/Stages/AccountStage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Button, Select, TextInput } from "@repo/ui";

import type { MouseEvent } from "react";
import { useState } from "react";
import type { SubmitHandler } from "react-hook-form";
import { Controller, FormProvider, useForm } from "react-hook-form";
import { mainAddress, regionList } from "../../../libs/regionList";
import Label from "../components/label/Label";
import ResetPasswordDialog from "../components/resetPasswordDialog/ResetPasswordDialog";
import {
buttonWrapper,
form,
Expand All @@ -16,6 +18,8 @@ import {
* @todo : 입력한 정보가 있을때는 해당 데이터를 가져와야함
*/
const AccountStage = () => {
const [isOpenResetPasswordDialog, setIsOpenResetPasswordDialog] =
useState(false);
const [isOpenAddressOption, setIsOpenAddressOption] = useState({
mainAddress: false,
subAddress: false,
Expand Down Expand Up @@ -69,6 +73,10 @@ const AccountStage = () => {
referenceCode: "ABCDEF",
};

const handleOpenResetPassword = (e: MouseEvent) => {
setIsOpenResetPasswordDialog(true);
};

return (
<FormProvider {...method}>
<form className={form} onSubmit={handleSubmit(onSubmit)}>
Expand Down Expand Up @@ -157,7 +165,7 @@ const AccountStage = () => {
<Button
variant="primary"
className={pwChange}
// onClick={() => 모달 열기}
onClick={handleOpenResetPassword}
>
비밀번호 변경하기
</Button>
Expand All @@ -176,6 +184,13 @@ const AccountStage = () => {
</Button>
</div>
</form>
{isOpenResetPasswordDialog && (
<ResetPasswordDialog
isOpen={isOpenResetPasswordDialog}
onClose={() => setIsOpenResetPasswordDialog(false)}
isMobile={false}
/>
)}
</FormProvider>
);
};
Expand Down
31 changes: 26 additions & 5 deletions apps/user/src/shared/components/myPage/Stages/OptionalStage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { Button, CheckBox, Radio, Select, Tag, TextInput } from "@repo/ui";
import {
Button,
CheckBox,
Radio,
Select,
Tag,
Textarea,
TextInput,
} from "@repo/ui";

import { useState } from "react";
import type { SubmitHandler } from "react-hook-form";
import { Controller, FormProvider, useForm } from "react-hook-form";
import { mypageError, myPageLimit } from "../../../libs/formErrorText";
import { drinkList, mbtiList, othersList } from "../../../libs/optionList";
import CountText from "../components/countText/CountText";
import Label from "../components/label/Label";
import {
buttonWrapper,
checkBoxWrapper,
countWrapper,
form,
radioWrapper,
section,
Expand Down Expand Up @@ -77,7 +87,13 @@ const OptionalStage = () => {
/>
</div>
<div>
<Label>특기</Label>
<div className={countWrapper}>
<Label>특기</Label>
<CountText
count={watch("skill")?.length}
limit={myPageLimit.skill.max}
/>
</div>
<TextInput
placeholder="특기를 입력해주세요"
width="100%"
Expand All @@ -91,10 +107,15 @@ const OptionalStage = () => {
/>
</div>
<div>
<Label>자기소개</Label>
<TextInput
<div className={countWrapper}>
<Label>자기소개</Label>
<CountText
count={watch("introduce")?.length}
limit={myPageLimit.introduce.max}
/>
</div>
<Textarea
placeholder="간단한 자기소개를 입력해주세요"
width="100%"
errorMessage={errors.introduce?.message}
{...register("introduce", {
maxLength: {
Expand Down
Loading