Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
099ebc8
feat: Chevron Right 이미지 추가
YeBeenChoi Jan 26, 2026
60de1a6
feat: 찜 svg 파일 수정
YeBeenChoi Jan 26, 2026
c80f363
chore: 공용 아이콘 export 추가
YeBeenChoi Jan 26, 2026
cfb1697
chore: 아이콘 export 추가
YeBeenChoi Jan 26, 2026
e844088
feat: RepairList 컴포넌트 구현
YeBeenChoi Jan 26, 2026
3294586
feat: RepairList 컴포넌트 export 추가
YeBeenChoi Jan 26, 2026
bb11959
feat: Picture svg 이미지 추가
YeBeenChoi Jan 26, 2026
4ca1a26
feat: 마이페이지 라우트 등록 및 구성 정리
YeBeenChoi Jan 26, 2026
5facd2c
feat: 마이페이지 라우트 엔트리 추가
YeBeenChoi Jan 26, 2026
98851da
feat: 개인 정보 관리 라우트 추가
YeBeenChoi Jan 26, 2026
a7ac01c
feat: 계정 설정 라우트 추가
YeBeenChoi Jan 26, 2026
e8e8967
refactor: 프로필 컴포넌트 사이즈 스펙 조정
YeBeenChoi Jan 26, 2026
2943a32
refactor: TradeItem 컴포넌트 UI 동작 보정
YeBeenChoi Jan 26, 2026
6e469ad
feat: 마이페이지 진입점 추가
YeBeenChoi Jan 26, 2026
5887be8
chore: 마이페이지용 목데이터 추가
YeBeenChoi Jan 26, 2026
eabf348
feat: 마이페이지 탭/콘텐츠 구성
YeBeenChoi Jan 26, 2026
50eeb9d
feat: 계정 설정 화면 UI 및 프로필 변경 기능 추가
YeBeenChoi Jan 26, 2026
edf741c
feat: 개인 정보 수정 기능 추가
YeBeenChoi Jan 26, 2026
df3532e
feat: 요약된 프로필 카드 컴포넌트 제작
YeBeenChoi Jan 26, 2026
82fa21e
feat: 마이페이지 상단 탭 컴포넌트 구현
YeBeenChoi Jan 26, 2026
6383556
feat: 찜한 목록 탭 활성 라인 추가
YeBeenChoi Jan 26, 2026
961d821
feat: 상태 탭 활성 라인 추가
YeBeenChoi Jan 26, 2026
7dc870f
feat: 빈 상태 문구 위치/타이포 설정
YeBeenChoi Jan 26, 2026
17c75b6
feat: 개인정보 입력값 저장 및 제출 처리 추가
YeBeenChoi Jan 26, 2026
18d2a60
feat: 마이페이지 계정 설정 메뉴 UI 구성 추가
YeBeenChoi Jan 26, 2026
b6b1889
feat: 마이페이지 레이아웃 컨테이너 추가
YeBeenChoi Jan 26, 2026
e604737
feat: 프로필 정보 로컬 저장/로드 유틸 추가
YeBeenChoi Jan 26, 2026
77eebab
feat: 불필요한 컴포넌트 삭제
YeBeenChoi Jan 26, 2026
6d980c5
feat: 프로필 정보 로컬 저장/로드 유틸 추가
YeBeenChoi Jan 26, 2026
2d57670
feat: 프로필 사진 변경 시 저장값 반영 처리
YeBeenChoi Jan 26, 2026
a123a0f
feat: 개인정보 저장 후 마이페이지 이동 처리
YeBeenChoi Jan 26, 2026
956022a
feat: 헤더 및 슬로건 구현
jwj0620gcu Jan 23, 2026
1458f59
feat: 제목 및 제조사 필드
jwj0620gcu Jan 24, 2026
ed93ce4
feat:드롭 다운 변경 및 모델명, 색상, 저장 용량 필드 구현
jwj0620gcu Jan 24, 2026
98287f2
feat:가격 필드 구현
jwj0620gcu Jan 24, 2026
29fa322
feat: 상품 상태 및 상세 설명 구현
jwj0620gcu Jan 24, 2026
136831d
feat :레이아웃 정리
jwj0620gcu Jan 24, 2026
de44331
feat:판매확인 페이지 ui 구성
jwj0620gcu Jan 25, 2026
0df5bde
삭제 토스트용 svg 추가
jwj0620gcu Jan 25, 2026
4b213a9
판매확인 페이지 default 이미지 추가
jwj0620gcu Jan 25, 2026
fdbbd49
피그마 디자인 변경으로 인한 모달 디자인 변경
jwj0620gcu Jan 25, 2026
d262fb3
fix: 가격 suffix 스타일 분리
jwj0620gcu Jan 25, 2026
5c7b3cc
feat: 메인 레이아웃 헤더와 토스트 통합
jwj0620gcu Jan 25, 2026
8e2eb3e
feat: 판매 폼 유효성 검사와 이미지 제한 추가
jwj0620gcu Jan 25, 2026
11a00bf
style: 판매 확인 페이지 문구 줄바꿈 적용
jwj0620gcu Jan 25, 2026
4a491b1
feat: 판매 관련 라우트 추가
jwj0620gcu Jan 25, 2026
368ec57
chore: 아이콘 export 정리
jwj0620gcu Jan 25, 2026
30cc539
style: spacing 토큰 추가
jwj0620gcu Jan 25, 2026
a8b7e56
fix: lint 오류 및 접근성 경고 수정
jwj0620gcu Jan 25, 2026
f9578a1
feat: 메인페이지 카드 섹션 및 캐러셀 자리 레이아웃 구성
YeBeenChoi Jan 24, 2026
7d00f94
feat: 메인페이지에 ChatbotFloatingButton 배치
YeBeenChoi Jan 24, 2026
1690f49
feat: 챗봇 버튼 클릭 시 이동 기능 추가
YeBeenChoi Jan 24, 2026
e902b0e
fix: 메인 페이지 머지 오류 해결
jwj0620gcu Jan 25, 2026
5c27992
refactor:모달 컴포넌트에서 배경 처리, 중복 코드 제거
jwj0620gcu Jan 26, 2026
dc87d67
refactor:타입 분리
jwj0620gcu Jan 26, 2026
02a290e
refactor:상수 스키마에서 통일
jwj0620gcu Jan 26, 2026
2a60b00
wip:sell-confrim 수정
jwj0620gcu Jan 26, 2026
bf6d80c
Update src/pages/sell-confirm/ui/SellConfirmPage.tsx
jwj0620gcu Jan 26, 2026
7b695a1
Update src/pages/sell-confirm/ui/SellConfirmPage.tsx
jwj0620gcu Jan 26, 2026
8331214
refactor: 개별 useState에서 react hook from 통한 상태/검증
jwj0620gcu Jan 26, 2026
3fafeac
Update src/pages/sell/ui/SellPage.tsx
jwj0620gcu Jan 26, 2026
4f9896d
refactor:드롭다운 분리
jwj0620gcu Jan 26, 2026
447d2eb
라디오버튼 반복 부분 배열, map으로 변경
jwj0620gcu Jan 26, 2026
f8c1826
feat:반응형 추가
jwj0620gcu Jan 26, 2026
1145409
비즈니스 모델 로직 분리
jwj0620gcu Jan 26, 2026
154b887
refactor: 토스트 컨텍스트 분리 및 훅 분리
jwj0620gcu Jan 26, 2026
dcecd26
fix: sell page 오류 정리
jwj0620gcu Jan 26, 2026
186c496
fix:test 오류 수정
jwj0620gcu Jan 26, 2026
e3da4e9
fix:lint 오류 해결
jwj0620gcu Jan 26, 2026
9bdfbe0
style:prettier 포맷 적용
jwj0620gcu Jan 26, 2026
45de47a
fix:test 오류 해결
jwj0620gcu Jan 26, 2026
fe1df95
refactor:이미지 검증 share로 이동 및 파일명 변경
jwj0620gcu Jan 26, 2026
92da65d
refactor: padding left 제거
jwj0620gcu Jan 26, 2026
12e1a8b
feat: Carousel3D 및 ClientOnly 컴포넌트 추가
KyeongJooni Jan 25, 2026
262bdf6
feat: 메인페이지에 Carousel3D 적용 및 배너카드 분리
KyeongJooni Jan 25, 2026
ca37cf3
refactor: pages ui 레이어 배럴 export 추가
KyeongJooni Jan 25, 2026
731a63f
refactor: useClickOutside 및 useImageUpload 훅 추출
KyeongJooni Jan 25, 2026
38eb04f
fix: Checkbox import 경로 @shared alias로 수정
KyeongJooni Jan 25, 2026
081f212
chore: 의존성 업데이트
KyeongJooni Jan 25, 2026
9573444
refactor: Button, Checkbox, RadioButton Tailwind 단축형 클래스 마이그레이션
KyeongJooni Jan 25, 2026
2f51eaf
refactor: TextField, SearchBar Tailwind 단축형 클래스 마이그레이션
KyeongJooni Jan 25, 2026
45c0215
refactor: Chat 컴포넌트 Tailwind 단축형 클래스 마이그레이션
KyeongJooni Jan 25, 2026
af9cfac
refactor: Modal, TradeItem, Carousel3D, ChatbotFloatingButton Tailwin…
KyeongJooni Jan 25, 2026
374cffb
test: 테스트 수정
KyeongJooni Jan 25, 2026
93200ec
refactor: 대용량 SVG를 WebP로 교체하여 빌드 사이즈 최적화
KyeongJooni Jan 25, 2026
e0ce56a
fix: rounded-l을 rounded-(--radius-l)로 수정하여 border-radius 복원
KyeongJooni Jan 25, 2026
9172481
refactor: main 페이지 데이터 파일명 PascalCase로 통일
KyeongJooni Jan 26, 2026
daee20b
refactor: images 폴더 이미지 WebP로 변환하여 빌드 사이즈 최적화
KyeongJooni Jan 26, 2026
042ffce
refactor: login 배경 이미지 WebP로 변환 및 배럴 파일 추가
KyeongJooni Jan 26, 2026
898094c
chore: 공용 아이콘 export 추가
YeBeenChoi Jan 26, 2026
d3491e0
chore: 아이콘 export 추가
YeBeenChoi Jan 26, 2026
49e86c7
feat: 마이페이지 라우트 등록 및 구성 정리
YeBeenChoi Jan 26, 2026
f815036
style: 하드코딩된 색상 값 토큰으로 변경
YeBeenChoi Jan 26, 2026
e35bf2a
fix: 개인정보 폼 입력값 초기화 반복 버그 수정
YeBeenChoi Jan 26, 2026
d156a5c
fix: 중복된 route id 제거
YeBeenChoi Jan 26, 2026
d307f9d
fix: RepairList 컴포넌트가 깨지는 오류 수정
YeBeenChoi Jan 26, 2026
a428877
Merge branch 'main' into 57-feat/마이페이지-UI-구현
YeBeenChoi Jan 26, 2026
b8dbeda
feat: Chevron Right 이미지 추가
YeBeenChoi Jan 26, 2026
55f1c00
feat: 찜 svg 파일 수정
YeBeenChoi Jan 26, 2026
15addbf
chore: 공용 아이콘 export 추가
YeBeenChoi Jan 26, 2026
2746baf
chore: 아이콘 export 추가
YeBeenChoi Jan 26, 2026
be6964b
feat: RepairList 컴포넌트 구현
YeBeenChoi Jan 26, 2026
7137c3e
feat: RepairList 컴포넌트 export 추가
YeBeenChoi Jan 26, 2026
e1779b6
feat: Picture svg 이미지 추가
YeBeenChoi Jan 26, 2026
d7981e4
feat: 마이페이지 라우트 등록 및 구성 정리
YeBeenChoi Jan 26, 2026
730fcde
feat: 마이페이지 라우트 엔트리 추가
YeBeenChoi Jan 26, 2026
9049a94
feat: 개인 정보 관리 라우트 추가
YeBeenChoi Jan 26, 2026
3f6a414
feat: 계정 설정 라우트 추가
YeBeenChoi Jan 26, 2026
a090935
refactor: 프로필 컴포넌트 사이즈 스펙 조정
YeBeenChoi Jan 26, 2026
ea25465
refactor: TradeItem 컴포넌트 UI 동작 보정
YeBeenChoi Jan 26, 2026
913feca
feat: 마이페이지 진입점 추가
YeBeenChoi Jan 26, 2026
de2fbac
chore: 마이페이지용 목데이터 추가
YeBeenChoi Jan 26, 2026
e662e73
feat: 마이페이지 탭/콘텐츠 구성
YeBeenChoi Jan 26, 2026
2f10ca5
feat: 계정 설정 화면 UI 및 프로필 변경 기능 추가
YeBeenChoi Jan 26, 2026
e369ade
feat: 개인 정보 수정 기능 추가
YeBeenChoi Jan 26, 2026
fd5afea
feat: 요약된 프로필 카드 컴포넌트 제작
YeBeenChoi Jan 26, 2026
5090591
feat: 마이페이지 상단 탭 컴포넌트 구현
YeBeenChoi Jan 26, 2026
d4e4233
feat: 찜한 목록 탭 활성 라인 추가
YeBeenChoi Jan 26, 2026
08358da
feat: 상태 탭 활성 라인 추가
YeBeenChoi Jan 26, 2026
48a78de
feat: 빈 상태 문구 위치/타이포 설정
YeBeenChoi Jan 26, 2026
1177142
feat: 개인정보 입력값 저장 및 제출 처리 추가
YeBeenChoi Jan 26, 2026
b670ffa
feat: 마이페이지 계정 설정 메뉴 UI 구성 추가
YeBeenChoi Jan 26, 2026
d563673
feat: 마이페이지 레이아웃 컨테이너 추가
YeBeenChoi Jan 26, 2026
474463b
feat: 프로필 정보 로컬 저장/로드 유틸 추가
YeBeenChoi Jan 26, 2026
62816c5
feat: 불필요한 컴포넌트 삭제
YeBeenChoi Jan 26, 2026
1d55007
feat: 프로필 정보 로컬 저장/로드 유틸 추가
YeBeenChoi Jan 26, 2026
51c9333
feat: 프로필 사진 변경 시 저장값 반영 처리
YeBeenChoi Jan 26, 2026
48af7c2
feat: 개인정보 저장 후 마이페이지 이동 처리
YeBeenChoi Jan 26, 2026
49da177
feat: 판매 관련 라우트 추가
jwj0620gcu Jan 25, 2026
80bcd79
chore: 아이콘 export 정리
jwj0620gcu Jan 25, 2026
bb2119c
feat: 메인페이지 카드 섹션 및 캐러셀 자리 레이아웃 구성
YeBeenChoi Jan 24, 2026
e7c8888
feat: 메인페이지에 Carousel3D 적용 및 배너카드 분리
KyeongJooni Jan 25, 2026
e7a2642
refactor: Modal, TradeItem, Carousel3D, ChatbotFloatingButton Tailwin…
KyeongJooni Jan 25, 2026
15156a6
refactor: 대용량 SVG를 WebP로 교체하여 빌드 사이즈 최적화
KyeongJooni Jan 25, 2026
61d2f41
chore: 공용 아이콘 export 추가
YeBeenChoi Jan 26, 2026
3436c5f
chore: 아이콘 export 추가
YeBeenChoi Jan 26, 2026
df75299
feat: 마이페이지 라우트 등록 및 구성 정리
YeBeenChoi Jan 26, 2026
86f6c0a
style: 하드코딩된 색상 값 토큰으로 변경
YeBeenChoi Jan 26, 2026
1874eca
fix: 개인정보 폼 입력값 초기화 반복 버그 수정
YeBeenChoi Jan 26, 2026
463d8cf
fix: 중복된 route id 제거
YeBeenChoi Jan 26, 2026
2149cf0
fix: RepairList 컴포넌트가 깨지는 오류 수정
YeBeenChoi Jan 26, 2026
3420373
fix: 프로필 테스트 size=lg 기대값 변경
YeBeenChoi Jan 26, 2026
09518c1
feat: 헤더 및 슬로건 구현
jwj0620gcu Jan 23, 2026
cc4ea6e
feat: 제목 및 제조사 필드
jwj0620gcu Jan 24, 2026
699c354
Update SellPage.tsx
YeBeenChoi Jan 26, 2026
5496ece
fix: merge 충돌 해결
YeBeenChoi Jan 26, 2026
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
3 changes: 3 additions & 0 deletions src/app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export default [
index('routes/(main)/_index.tsx'),
route('sell', 'routes/(main)/sell.tsx'),
route('sell/confirm', 'routes/(main)/sell.confirm.tsx'),
route('mypage', 'routes/mypage.tsx'),
route('mypage/settings', 'routes/mypage-settings.tsx'),
route('mypage/profile', 'routes/mypage-profile.tsx'),
]),
route('playground', 'routes/playground.tsx'),
] satisfies RouteConfig;
3 changes: 3 additions & 0 deletions src/app/routes/mypage-profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ProfileInfoPage } from '@pages/mypage';

export default ProfileInfoPage;
3 changes: 3 additions & 0 deletions src/app/routes/mypage-settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { AccountSettingsPage } from '@pages/mypage';

export default AccountSettingsPage;
3 changes: 3 additions & 0 deletions src/app/routes/mypage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { MyPage } from '@pages/mypage';

export default MyPage;
26 changes: 1 addition & 25 deletions src/pages/main/ui/MainPage.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,14 @@
import { ChatCircleCloseIcon } from '@shared/assets/icons';
import { ROUTES } from '@shared/constants';
import { useToast } from '@shared/hooks';
import { BannerCard } from '@shared/ui/BannerCard';
import { Carousel3D } from '@shared/ui/Carousel3D';
import { ChatbotFloatingButton } from '@shared/ui/ChatbotFloatingButton';
import { ClientOnly } from '@shared/ui/ClientOnly';
import { useEffect, useRef } from 'react';
import { useLocation, useNavigate } from 'react-router';
import { useNavigate } from 'react-router';
import { BANNER_CARDS } from './BannerCards';
import { CAROUSEL_SLIDES } from './CarouselSlides';

type MainLocationState = {
deleted?: boolean;
};

export default function MainPage() {
const location = useLocation();
const navigate = useNavigate();
const { showToast } = useToast();
const didShowDeleteToast = useRef(false);

useEffect(() => {
const state = location.state as MainLocationState | null;
if (state?.deleted && !didShowDeleteToast.current) {
didShowDeleteToast.current = true;
showToast('삭제되었습니다!', {
tone: 'info',
icon: (
<ChatCircleCloseIcon className="h-6 w-6 text-[var(--color-gray-900)] [&_*]:stroke-[var(--color-gray-900)] [&_*]:stroke-[2]" />
),
});
navigate(location.pathname, { replace: true, state: null });
}
}, [location.pathname, location.state, navigate, showToast]);

return (
<main className="flex w-full flex-col items-center gap-14 px-4 pt-8 pb-24">
Expand Down
44 changes: 44 additions & 0 deletions src/pages/main/ui/bannerCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { GearIcon, SellIcon, ShoppingIcon } from '@shared/assets/icons';
import { ROUTES } from '@shared/constants';

export const BANNER_CARDS = [
{
id: 'buy',
title: (
<>
중고 전자기기
<br />
구매하기
</>
),
description: '합리적인 매물을 찾아보세요.',
imageSrc: ShoppingIcon,
route: ROUTES.BUY,
},
{
id: 'sell',
title: (
<>
중고 전자기기
<br />
판매하기
</>
),
description: '사용하지 않는 기기를 판매해보세요.',
imageSrc: SellIcon,
route: ROUTES.SELL,
},
{
id: 'repair',
title: (
<>
근처
<br />
수리점 찾기
</>
),
description: '가까운 수리점을 찾아드려요.',
imageSrc: GearIcon,
route: ROUTES.REPAIR,
},
];
39 changes: 39 additions & 0 deletions src/pages/main/ui/carouselSlides.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
PhoneRecycleImage,
PhoneRepairImage,
PhoneSellImage,
SloganImage,
SmartphoneImage,
} from '@shared/assets/images';
import { CarouselImageSlide } from '@shared/ui/Carousel3D';

export const CAROUSEL_SLIDES = [
{
id: 1,
content: (
<CarouselImageSlide imageSrc={SloganImage} title="버리기 전, 루핏" subtitle="Before you throw out, LOOPIT" />
),
},
{
id: 2,
content: (
<CarouselImageSlide imageSrc={SmartphoneImage} title="중고폰 구매" subtitle="검증된 중고폰을 합리적인 가격에" />
),
},
{
id: 3,
content: (
<CarouselImageSlide imageSrc={PhoneSellImage} title="내 폰 판매" subtitle="안 쓰는 폰, 현금으로 바꾸세요" />
),
},
{
id: 4,
content: (
<CarouselImageSlide imageSrc={PhoneRepairImage} title="수리점 찾기" subtitle="가까운 수리점을 찾아드려요" />
),
},
{
id: 5,
content: <CarouselImageSlide imageSrc={PhoneRecycleImage} title="친환경 순환" subtitle="버려지는 폰에 새 생명을" />,
},
];
3 changes: 3 additions & 0 deletions src/pages/mypage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as MyPage } from './ui/MyPage';
export { default as AccountSettingsPage } from './ui/AccountSettingsPage';
export { default as ProfileInfoPage } from './ui/ProfileInfoPage';
76 changes: 76 additions & 0 deletions src/pages/mypage/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import type { TradeListItem } from '../ui/components/TradeItemList';
import type { RepairListItem } from '@shared/ui/RepairList';

export const MY_PAGE_PROFILE = {
nickname: '폰박살',
email: 'loveloopit@email.com',
profileImage: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?q=80&w=320&auto=format&fit=crop',
};

export const PERSONAL_INFO_DEFAULTS = {
nickname: '폰박살',
name: '김민아',
birthDate: '2001-11-11',
email: 'loveloopit@email.com',
};

export const BUY_ITEMS: TradeListItem[] = [
{
id: 'buy-1',
modelName: '아이폰 17 256GB 실버',
price: '1,450,000원',
date: '2026.02.09',
status: 'buying',
imageUrl: 'https://images.unsplash.com/photo-1512499617640-c2f999018b72?q=80&w=200&auto=format&fit=crop',
},
];

export const SELL_ITEMS: TradeListItem[] = [
{
id: 'sell-1',
modelName: '아이폰 16 프로 512GB',
price: '1,320,000원',
date: '2026.02.07',
status: 'reserved',
imageUrl: 'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?q=80&w=200&auto=format&fit=crop',
},
{
id: 'sell-2',
modelName: '갤럭시 S26 울트라',
price: '1,550,000원',
date: '2026.01.30',
status: 'completed',
statusLabel: '판매완료',
imageUrl: 'https://images.unsplash.com/photo-1510557880182-3d4d3cba35a5?q=80&w=200&auto=format&fit=crop',
},
];

export const FAVORITE_PRODUCT_ITEMS: TradeListItem[] = [
{
id: 'fav-product-1',
modelName: '새제품 아이폰 17 256GB',
price: '1,500,000원',
date: '2026.02.08',
status: 'favorite',
favoriteActive: true,
imageUrl: 'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?q=80&w=200&auto=format&fit=crop',
},
{
id: 'fav-product-2',
modelName: '아이폰 17 (새제품, 케이스 증정)',
price: '1,550,000원',
date: '2026.02.07',
status: 'favorite',
favoriteActive: true,
imageUrl: 'https://images.unsplash.com/photo-1512499617640-c2f999018b72?q=80&w=200&auto=format&fit=crop',
},
];

export const FAVORITE_REPAIR_ITEMS: RepairListItem[] = [
{
id: 'fav-repair-1',
name: '뚝딱 핸드폰수리점',
address: '서울시 강남구',
favoriteActive: true,
},
];
78 changes: 78 additions & 0 deletions src/pages/mypage/ui/AccountSettingsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { ChevronRightIcon, PictureIcon } from '@shared/assets/icons';
import { Profile } from '@shared/ui/Profile';
import { useRef, useState } from 'react';
import { useNavigate } from 'react-router';
import { MY_PAGE_PROFILE } from '../mocks';
import { getProfileSummary, saveProfile } from '../utils/profileStorage';
import { PageContainer } from './components/PageContainer';

export default function AccountSettingsPage() {
const navigate = useNavigate();
const profileSummary = getProfileSummary();
const [profileImage, setProfileImage] = useState(profileSummary.profileImage ?? MY_PAGE_PROFILE.profileImage);
const fileInputRef = useRef<HTMLInputElement | null>(null);

const handleProfileClick = () => {
fileInputRef.current?.click();
};

const handleProfileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) {
return;
}
const reader = new FileReader();
reader.onload = () => {
if (typeof reader.result !== 'string') {
return;
}
setProfileImage(reader.result);
saveProfile({ profileImage: reader.result });
};
reader.readAsDataURL(file);
};

return (
<main className="min-h-screen bg-white">
<PageContainer>
<h1 className="typo-title-2 text-gray-900">계정 설정</h1>

<div className="mt-[40px] flex flex-col items-center">
<div className="relative inline-flex h-45 w-45">
<Profile size="lg" image={profileImage} alt={`${profileSummary.nickname} 프로필`} />
<button
type="button"
onClick={handleProfileClick}
className="absolute right-[8px] bottom-[8px] flex h-[40px] w-[40px] items-center justify-center rounded-full border border-[#C7C7CC] bg-white p-[8px]"
aria-label="프로필 사진 변경"
>
<PictureIcon className="h-4.5 w-4.5 text-gray-500" />
</button>
<input ref={fileInputRef} type="file" accept="image/*" className="sr-only" onChange={handleProfileChange} />
</div>
</div>

<section className="mt-12.25">
<h2 className="typo-title-2 text-gray-900">내 정보</h2>
<div className="mt-[40px] flex flex-col gap-12.25">
<button
type="button"
onClick={() => navigate('/mypage/profile', { viewTransition: true })}
className="flex h-11 w-full items-center justify-between px-[10px] py-[10px] text-left"
>
<span className="typo-body-1 text-gray-900">개인정보 관리</span>
<ChevronRightIcon className="h-6 w-5.75 text-gray-900" />
</button>
<button
type="button"
className="flex h-11 w-full items-center justify-between px-[10px] py-[10px] text-left"
>
<span className="typo-body-1 text-gray-900">로그아웃</span>
<ChevronRightIcon className="h-6 w-5.75 text-gray-900" />
</button>
</div>
</section>
</PageContainer>
</main>
);
}
Loading
Loading