From 4346e5559cece47844549bc2bca9425b96c6a48a Mon Sep 17 00:00:00 2001 From: jeschun Date: Sun, 19 Oct 2025 20:08:28 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/my-profile/index.tsx | 215 +++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 90 deletions(-) diff --git a/src/pages/my-profile/index.tsx b/src/pages/my-profile/index.tsx index 4c5ef50..b28a440 100644 --- a/src/pages/my-profile/index.tsx +++ b/src/pages/my-profile/index.tsx @@ -1,3 +1,4 @@ +// src/pages/my-profile/index.tsx import Image from 'next/image'; import Link from 'next/link'; import { useEffect, useMemo, useState } from 'react'; @@ -46,124 +47,158 @@ export default function MyProfileDetailPage() { startsAt: a.notice.item.startsAt, workhour: a.notice.item.workhour, status, - // employee 표에서는 미사용 — 타입만 충족 bio: '', phone: '', }; }); }, [applications]); - const pagedRows = useMemo(() => rows.slice(offset, offset + limit), [rows, offset]); + // 로딩 중에도 마지막 성공 데이터를 유지 (화면 흔들림 방지) + const [stableRows, setStableRows] = useState([]); + const [stableTotal, setStableTotal] = useState(0); + useEffect(() => { + if (rows.length > 0) { + setStableRows(rows); + setStableTotal(applications.length); + } + }, [rows, applications.length]); - // rows 변화 시 첫 페이지로 리셋 (페이지네이션 UX 보강) + // rows 변화 시 첫 페이지로 리셋 useEffect(() => { setOffset(0); }, [rows.length]); - return ( -
-
-

내 프로필

+ const currentRows = rows.length > 0 ? rows : stableRows; + const currentTotal = rows.length > 0 ? applications.length : stableTotal; + + const pagedRows = useMemo(() => currentRows.slice(offset, offset + limit), [currentRows, offset]); - {/* 프로필이 없으면 등록 프레임 */} + return ( +
+ {/* 공통 컨테이너: Table과 좌측선/폭 동일 */} +
{profileIsEmpty ? ( - + <> +

내 프로필

+
+ +
+ ) : ( - // 프로필 카드(피그마 스타일) -
-
-
-

이름

-

- {user?.name || '—'} -

- - {/* 연락처 */} -
- 전화 - {user?.phone || '—'} -
- - {/* 선호 지역 */} -
- 지도 - 선호 지역: {(user?.address as string) || '—'} -
+ // ✅ 데스크탑에서 제목과 카드가 같은 flex 라인에 놓이도록 +
+

+ 내 프로필 +

- {/* 소개 */} - {user?.bio && ( -

- {user.bio} +

+
+
+

이름

+

+ {user?.name || '—'}

- )} -
- {/* 우상단 편집 버튼 */} -
- + {/* 연락처 */} +
+ 전화 + {user?.phone || '—'} +
+ + {/* 선호 지역 */} +
+ 지도 + + 선호 지역: {(user?.address as string) || '—'} + +
+ + {/* 소개 */} + {user?.bio && ( +

+ {user.bio} +

+ )} +
+ + {/* 우상단 편집 버튼 */} +
+ +
-
-
+ +
)}
- {/* 신청 내역 — 프로필 있고 로그인 상태일 때만 */} + {/* 하단: 신청 내역 — 프로필 있고 로그인 상태일 때만 */} {!profileIsEmpty && isLogin && ( -
- {isLoading ? ( -
불러오는 중…
- ) : rows.length === 0 ? ( -
+
+
+ {isLoading && currentRows.length === 0 ? ( + <> +
+

신청 내역

+
+
+
+ {[...Array(5)].map((_, i) => ( +
+ ))} +
+
+ + ) : currentRows.length === 0 ? ( -
- ) : ( -
- - - )} + ) : ( +
+
+ + )} + )} From 01640bd2320cc3b1ee627b46f10214add8b48436 Mon Sep 17 00:00:00 2001 From: jeschun Date: Sun, 19 Oct 2025 21:59:51 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=ED=95=84=EC=88=98=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=ED=95=84=EB=93=9C=EC=97=90=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/my-profile/register.tsx | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/pages/my-profile/register.tsx b/src/pages/my-profile/register.tsx index 3a68053..2038ca5 100644 --- a/src/pages/my-profile/register.tsx +++ b/src/pages/my-profile/register.tsx @@ -14,7 +14,7 @@ type ProfileForm = { name: string; phone: string; region: AddressCode | ''; - bio: string; + bio: string; // bio는 선택 }; export default function MyProfileRegisterPage() { @@ -76,12 +76,12 @@ export default function MyProfileRegisterPage() { setIsSubmitting(true); try { - // 서버 반영 + 컨텍스트 동기화 + // 서버 반영 + 컨텍스트 동기화 await updateUser({ name: formState.name.trim(), phone: formState.phone.trim(), address: formState.region, - bio: formState.bio, + bio: formState.bio, // bio는 선택(빈 문자열 가능) }); setIsDoneOpen(true); } finally { @@ -100,6 +100,7 @@ export default function MyProfileRegisterPage() { > +

내 프로필

{ @@ -123,16 +124,21 @@ export default function MyProfileRegisterPage() { onBlur={() => setNameErrorMessage(formState.name.trim() ? null : '이름을 입력해 주세요.') } - required + required // HTML5 required error={nameErrorMessage ?? undefined} /> + {nameErrorMessage && ( +

+ {nameErrorMessage} +

+ )} {/* 연락처 */}
{ @@ -149,6 +155,11 @@ export default function MyProfileRegisterPage() { required error={phoneErrorMessage ?? undefined} /> + {phoneErrorMessage && ( +

+ {phoneErrorMessage} +

+ )}
{/* 선호 지역 */} @@ -170,7 +181,9 @@ export default function MyProfileRegisterPage() { className='w-full' /> {regionErrorMessage && ( -

{regionErrorMessage}

+

+ {regionErrorMessage} +

)} @@ -178,7 +191,7 @@ export default function MyProfileRegisterPage() { {/* 소개(선택) */}