Skip to content

[FEAT] 설정 페이지 개인정보·탈퇴 화면 구현#127

Open
jjangminii wants to merge 17 commits into
developfrom
feat/web/122-settings-page-view
Open

[FEAT] 설정 페이지 개인정보·탈퇴 화면 구현#127
jjangminii wants to merge 17 commits into
developfrom
feat/web/122-settings-page-view

Conversation

@jjangminii

@jjangminii jjangminii commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

ISSUE 🔗

close #122



What is this PR? 🔍

설정(Settings) 페이지의 개인정보 화면과 회원 탈퇴 화면을 Figma 디자인 기준으로 구현하고, 한/영 다국어를 적용했습니다.

배경

  • 기존 구조: settings/page.tsxsettings/withdrawal/page.tsx는 헤더(h1)만 있고 실제 콘텐츠가 없는 뼈대 상태였습니다.
  • 발생 문제: 프로필/캘린더 연동/언어/태그/탈퇴 등 설정 기능이 전혀 동작하지 않았고, 사이드바 하위 메뉴와 버튼 텍스트도 번역 키 없이 한국어로 고정되어 있었습니다.
  • 해결 방향: Figma 화면설계서의 컴포넌트·동작 규칙을 기준으로 개인정보/탈퇴 화면을 구현하고, 아직 없는 팝업·모달 UI는 window.confirm/prompt/alert로 임시 대체했습니다. 태그·버튼 등 반복되는 UI는 디자인 시스템 공용 컴포넌트로 분리했습니다.

설정 사이드바

  • 변경 요약: 설정 하위 네비게이션(개인 정보/약관/회원 탈퇴)에 다국어 번역을 적용하고, 콘텐츠 영역만 스크롤되도록 레이아웃을 고쳤습니다.
  • 이유: 기존에는 nav와 콘텐츠가 같은 스크롤 컨테이너에 있어 사이드바까지 함께 스크롤됐고, 하위 메뉴 라벨도 하드코딩된 한국어였습니다.
  • 구현 방식: layout.tsx에서 스크롤 컨테이너를 main에만 적용(overflow-hidden + overflow-y-auto)해 사이드바를 고정시켰습니다. SettingsNavContaineruseTranslations("Settings")nav.account/nav.policy/nav.withdrawal 키를 조회하고, 최상단 "설정" 타이틀은 기존 Navigation.settings 키를 재사용해 중복 정의를 피했습니다.

개인정보 화면

  • 변경 요약: 프로필 표시, 구글 캘린더 연동, 언어 전환, 태그 관리, 변경사항 저장 로직을 구현했습니다.
  • 이유: 화면설계서상 각 항목에 구체적인 동작 규칙([6-a]/[6-b] 연동 해제·연동, [10-a]/[10-b] 저장 버튼 활성화 조건 등)이 정의되어 있었고, 기존 뼈대에는 이 로직이 전혀 없었습니다.
  • 구현 방식: SettingsProfileContainerisDirty 플래그로 변경 여부를 추적해 저장 버튼 활성/비활성을 결정합니다. 캘린더 연동 해제 시 window.confirm으로 확인 팝업을 흉내 내고, 확인 시에만 상태를 되돌립니다. 언어 토글은 화면설계서 규칙("탭 전환 시 화면 언어는 즉시 바뀌지 않고 저장 버튼만 활성화")에 따라 클릭 시엔 draftLanguage state만 바꾸고, 저장 성공 시에만 @/i18n/navigationrouter.replace(pathname, { locale })로 실제 로케일을 전환합니다. 태그는 기본 태그(과제/업무/운동/일상)를 캐노니컬 키(assignment/work/exercise/dailyLife)로 저장하고 화면에서 Common.tag.*로 번역해, 로케일이 바뀌어도 기본/커스텀 태그 구분이 깨지지 않도록 했습니다. 태그 추가는 window.prompt placeholder에 10자 제한과 중복 검사를 추가했습니다.
  • 경계 · 제약: 실제 Google OAuth 연동, 태그 생성/삭제 모달, 로그아웃 후 로그인 페이지 이동은 이번 PR 범위 밖입니다. 로그인 라우트가 아직 없어 로그아웃은 콘솔 로그로만 의도를 남겨뒀습니다.

공용 버튼 컴포넌트

  • 변경 요약: 태그 칩·태그 추가·연동·로그아웃 버튼에서 반복되던 pill 스타일을 하나의 TagButton으로 먼저 묶었다가, 리뷰 과정에서 TagChip(태그 표시)과 PillButton(클릭 액션)으로 용도별로 다시 분리했습니다.

TagButton이라는 이름과 달리 실제로는 태그 표시(정적 기본 태그/삭제 가능한 커스텀 태그)와 캘린더 연동, 태그 추가, 로그아웃 같은 일반 클릭 액션까지 한 컴포넌트가 함께 떠맡고 있어 이름이 가리키는 역할과 실제 책임이 어긋났어요. variant·icon·onClick·onRemove 4개 prop을 모두 받다 보니, 소비처마다 실제로 쓰는 조합은 서로 겹치지 않는데도 onRemoveonClick 유무 순으로 분기하는 로직 하나에 섞여 있었습니다.

그래서 TagChip(packages/timo-design-system/src/components/tag/tag-chip)은 태그 표시 전용으로 onRemove 유무만으로 분기하고, variant·icon·onClick을 제거해 항상 gray 배경만 렌더링하도록 했어요.

PillButton(.../components/button/pill-button)은 반대로 onClick을 필수 prop으로 바꿔 클릭 가능한 액션(캘린더 연동 variant="blue", 태그 추가 icon, 로그아웃)만 담당합니다.
삭제 가능한 태그는 <button> 안에 <button>을 중첩할 수 없어 TagChip 바깥을 <div>로, 삭제 아이콘만 내부 <button>으로 렌더링하는 기존 구조는 그대로 유지했습니다.

태그 추가 버튼을 TagChip이 아니라 PillButton 으로 분류한 이유는 "태그 추가" 버튼은 실제 태그를 표시하는 게 아니라 클릭 가능한 액션(모달 열기/prompt 띄우기)이기 때문이에요. TagChip은 이번에 onRemove 유무로만 분기하는 순수 표시용 컴포넌트로 단순화했고 (onClick, icon prop을 아예 없앴음), 클릭 가능한 것들(캘린더 연동, 태그 추가, 로그아웃)은 전부 PillButton으로 모았습니다.

다국어(i18n) 지원

  • 변경 요약: 개인정보/탈퇴 화면의 h1·h2 라벨과 버튼 텍스트에 messages/ko.json·en.jsonSettings 네임스페이스 번역을 적용했습니다.
  • 이유: 사이드바 상위 탭은 이미 next-intl로 번역되고 있었는데, 설정 하위 화면들만 한국어로 고정되어 있어 /en 로케일 진입 시 일관성이 깨졌습니다.
  • 구현 방식: _components는 순수 UI 원칙에 따라 직접 번역 훅을 쓰지 않고, _containersuseTranslations로 만든 labels 객체를 prop으로 내려받습니다. 사용자가 직접 추가한 커스텀 태그(예: "안녕")는 번역 대상에서 제외했습니다.

회원 탈퇴 화면

  • 변경 요약: 탈퇴 안내 문구, 유의사항 박스, 탈퇴하기 버튼을 구현했습니다.
  • 이유: 화면설계서상 탈퇴 버튼 클릭 시 확인 팝업을 거쳐야 하는데 기존에는 화면 자체가 비어 있었습니다.
  • 구현 방식: 탈퇴 버튼 클릭 시 window.confirm으로 "정말 탈퇴하시겠어요?" 확인을 거치고, 확인 시에만 콘솔 로그로 탈퇴 처리 placeholder를 실행합니다. 디자인 시스템에 없던 경고 아이콘은 Figma에서 내려받아 warning-gray.svg 소스로 추가하고 icons:generateWarningGrayIcon을 생성했습니다(생성 산출물은 gitignore 대상이라 소스 SVG만 커밋에 포함됩니다).



To Reviewers

  • 팝업·모달이 필요한 지점(캘린더 연동 해제 확인, 태그 생성, 저장 실패 안내, 탈퇴 확인)은 전부 window.confirm/prompt/alert로 임시 처리했습니다. 실제 모달 컴포넌트로 교체하는 작업은 후속 PR로 남겨뒀습니다.
  • 언어 토글의 "저장 전까지 화면 언어 유지" 동작은 화면설계서 문구를 그대로 따른 것이라, 실제 기획 의도와 맞는지 한 번 더 확인 부탁드립니다.
  • SettingsProfile.tags가 캐노니컬 키(영문)와 커스텀 원문(한국어)을 한 배열에 섞어서 담는 구조라, 실제 API 연동 시에는 백엔드가 태그를 어떤 형태로 내려주는지에 따라 이 부분을 다시 다듬어야 할 수 있습니다.



Screenshot 📷

image image image
화면 ko en
개인정보 프로필/캘린더 연동/언어/태그 섹션 구현, 기본 태그는 삭제 불가·커스텀 태그만 삭제 가능 동일 레이아웃, Common.tag/Settings.profile 번역 적용
회원 탈퇴 유의사항 3가지 + 탈퇴하기 버튼, 클릭 시 confirm 팝업 노출 Figma 영문 카피("Withdraw") 그대로 반영



Test Checklist ✔

  • pnpm check-types 통과
  • pnpm lint 통과
  • Playwright로 /ko, /en 개인정보·탈퇴 화면 렌더링 및 텍스트 확인
  • Playwright로 언어 토글 클릭 시 URL 유지 → 저장 클릭 시 /en으로 전환되는 흐름 확인
  • Playwright로 캘린더 연동/해제, 태그 추가/삭제, 탈퇴 confirm 다이얼로그 동작 확인
  • pnpm build — 미실행: CI에서 확인 예정
  • 실제 Google OAuth 연동 — 후속 작업(현재는 목데이터)

- Figma 디자인 기반으로 개인정보/약관/회원탈퇴 공용 네비를 구현했습니다
- 각 서브페이지에 제목+구분선 뼈대를 연결했습니다
- 회원 탈퇴용 신규 라우트(/settings/withdrawal)를 추가했습니다
- 프로필/캘린더 연동/언어/태그 설정 폼을 구현했습니다
- 기본 제공 태그(과제, 업무, 운동, 일상)는 삭제 버튼을 숨기고, 사용자가 추가한 태그만 삭제 가능하도록 했습니다
- 스크롤 영역을 main에만 적용해 사이드바가 화면에 고정되도록 수정했습니다
- 태그 칩, 태그 추가, 연동 버튼, 로그아웃 버튼 등에서 공통으로 쓰이는 pill 스타일 버튼 컴포넌트를 추가했습니다
- 삭제 아이콘이 있는 태그는 버튼 중첩을 피하기 위해 내부에만 실제 버튼을 렌더링하도록 했습니다
- 개별 버튼들을 공통 TagButton 컴포넌트로 교체했습니다
- 구글 캘린더 연동 해제 시 확인 다이얼로그를, 태그 추가 시 입력 다이얼로그를 임시로 노출하도록 구현했습니다
- 변경사항 저장 버튼을 데이터 변경 여부에 따라 활성화하고, 저장 실패 시 안내 메시지를 노출하도록 구현했습니다
- 사이드바 하위 메뉴와 개인정보 폼의 h2 라벨·버튼 텍스트를 Settings 네임스페이스 번역 키로 교체했습니다 (사용자 추가 태그는 번역 대상에서 제외)
- 기본 태그를 캐노니컬 키로 저장하고 화면에서만 번역하도록 해서, 로케일과 무관하게 기본/커스텀 태그를 정확히 구분하도록 했습니다
- 언어 토글이 next-intl 로케일 라우팅과 실제로 연동되어 URL이 전환되도록 했습니다
- 구글 캘린더 연동 박스와 태그 목록의 불필요한 줄바꿈·여백 문제를 수정했습니다
- 언어 토글 클릭 시 하이라이트만 이동하고 변경사항 저장을 활성화하도록 하고, 실제 로케일 전환은 저장 성공 시에만 수행하도록 수정했습니다
- 로그아웃 시 로그인 페이지 이동 의도를 콘솔 로그로 남겨뒀습니다 (로그인 라우트가 아직 없어 실제 이동은 보류)
- Figma 디자인대로 탈퇴 안내 문구, 유의사항 박스, 탈퇴하기 버튼을 구현했습니다
- 탈퇴 버튼 클릭 시 확인 팝업(임시 window.confirm)을 노출하고, 확인 시에만 탈퇴 처리하도록 했습니다
- 다른 설정 페이지와 동일하게 Settings.withdrawal 네임스페이스로 한/영 번역을 적용했습니다
- 디자인 시스템에 없던 경고 아이콘을 WarningGrayIcon으로 추가했습니다
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
timo Ready Ready Preview, Comment Jul 10, 2026 6:58am

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

설정 프로필 편집, 설정 네비게이션·레이아웃, 정책 및 회원 탈퇴 화면이 추가되었습니다. 프로필은 언어·태그·캘린더·저장 상태를 관리하며, PillButton과 TagChip 디자인 시스템 컴포넌트 및 관련 번역·라우트가 함께 추가되었습니다.

Changes

설정 페이지 기능

Layer / File(s) Summary
설정 데이터 계약
apps/timo-web/app/[locale]/(main)/settings/_types/*, apps/timo-web/app/[locale]/(main)/settings/_mocks/profile-mock.ts
프로필, 폼 값, 태그, 라벨 및 탈퇴 화면에 필요한 타입과 목 데이터가 정의되었습니다.
설정용 공통 컨트롤
packages/timo-design-system/src/components/button/pill-button/*, packages/timo-design-system/src/components/tag/tag-chip/*, packages/timo-design-system/src/components/index.ts
PillButton과 TagChip의 공개 API, 렌더링 동작, Storybook 상태 예제가 추가되었습니다.
프로필 설정 흐름
apps/timo-web/app/[locale]/(main)/settings/_containers/SettingsProfileContainer.tsx, apps/timo-web/app/[locale]/(main)/settings/_components/SettingsProfileForm.tsx, apps/timo-web/app/[locale]/(main)/settings/page.tsx, apps/timo-web/package.json
프로필 화면에서 언어·태그·캘린더·로그아웃·저장 동작을 연결하고 react-hook-form으로 변경 및 제출 상태를 관리합니다.
설정 레이아웃과 네비게이션
apps/timo-web/app/[locale]/(main)/settings/layout.tsx, apps/timo-web/app/[locale]/(main)/settings/_containers/SettingsNavContainer.tsx, apps/timo-web/constants/routes.ts, apps/timo-web/app/[locale]/(main)/settings/policy/page.tsx
설정 사이드 네비게이션, 경로별 활성 상태, 본문 스크롤 레이아웃 및 정책 페이지 UI가 추가되었습니다.
회원 탈퇴 화면 흐름
apps/timo-web/app/[locale]/(main)/settings/withdrawal/*, apps/timo-web/messages/en.json, apps/timo-web/messages/ko.json
탈퇴 안내·경고·확인 UI와 번역을 추가하고, 확인 후 탈퇴 핸들러를 실행하도록 연결했습니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: ✨ Feature, ♦️ 민아

Suggested reviewers: ehye1, yumin-kim2, kimminna

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 설정 페이지의 개인정보·탈퇴 화면 구현이라는 핵심 변경을 정확히 요약합니다.
Description check ✅ Passed 설정 페이지의 개인정보/탈퇴 화면 구현과 i18n, 레이아웃 연결 내용을 PR 설명이 잘 반영합니다.
Linked Issues check ✅ Passed 직접 연결된 #122의 설정 페이지 실제 뷰, 메뉴/컨테이너 구현, page 연결 요구를 충족합니다.
Out of Scope Changes check ✅ Passed 설정 화면 구현에 필요한 라우트, 번역, 공용 컴포넌트 분리까지로 보이며 명확한 무관 변경은 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/web/122-settings-page-view

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/timo-web/app/`[locale]/(main)/settings/_containers/SettingsProfileContainer.tsx:
- Around line 64-79: The temporary dialog text in SettingsProfileContainer is
hardcoded in Korean, so replace the strings used by handleConnectCalendar and
the related dialog/toast helpers with translation keys via useTranslations. Add
the needed keys to the locale files, then read them in SettingsProfileContainer
instead of passing literal Korean text to window.confirm, window.prompt, and
window.alert so the same flow works for English users too.

In `@apps/timo-web/app/`[locale]/(main)/settings/policy/page.tsx:
- Around line 1-8: The SettingsPolicyPage component is hardcoding the page title
as Korean text, so replace that literal in SettingsPolicyPage with a translated
value from next-intl instead of rendering "약관" directly. Use useTranslations in
this Server Component to read the existing policy/nav translation key (for
example the same settings namespace used by tSettings("nav.policy")) and render
that value in the h1 so the locale switches correctly for all languages.

In
`@apps/timo-web/app/`[locale]/(main)/settings/withdrawal/_containers/SettingsWithdrawalContainer.tsx:
- Around line 25-32: Replace the temporary withdrawal flow in
SettingsWithdrawalContainer’s handleWithdraw with the real implementation
instead of the window.confirm placeholder and console.log stub. Hook the handler
up to the actual confirmation modal UI when available, and then call the
withdrawal API service for member deletion/data removal using the existing
handleWithdraw entry point so the TODOs are fully removed.

In `@packages/timo-design-system/src/components/button/tag-button/TagButton.tsx`:
- Around line 13-21: `TagButtonProps` currently allows `onRemove` without a
guaranteed accessible label, so update the `TagButton` types to use a
discriminated union where the branch with `onRemove` requires `removeLabel` and
the branch without `onRemove` disallows it or keeps it optional as appropriate.
Then adjust `TagButton` to rely on that type contract when setting the remove
button’s `aria-label`, using the `TagButton`/`TagButtonProps` symbols to find
the relevant props and render logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2fd93976-c4cd-4223-9bca-38ec73cfddc5

📥 Commits

Reviewing files that changed from the base of the PR and between 6e082b2 and d66f953.

⛔ Files ignored due to path filters (3)
  • apps/timo-web/public/images/google-calendar.png is excluded by !**/*.png
  • apps/timo-web/public/images/google-logo.png is excluded by !**/*.png
  • packages/timo-design-system/src/icons/source/warning-gray.svg is excluded by !**/*.svg
📒 Files selected for processing (19)
  • apps/timo-web/app/[locale]/(main)/settings/_components/SettingsProfileForm.tsx
  • apps/timo-web/app/[locale]/(main)/settings/_containers/SettingsNavContainer.tsx
  • apps/timo-web/app/[locale]/(main)/settings/_containers/SettingsProfileContainer.tsx
  • apps/timo-web/app/[locale]/(main)/settings/_mocks/profile-mock.ts
  • apps/timo-web/app/[locale]/(main)/settings/_types/profile-type.ts
  • apps/timo-web/app/[locale]/(main)/settings/layout.tsx
  • apps/timo-web/app/[locale]/(main)/settings/page.tsx
  • apps/timo-web/app/[locale]/(main)/settings/policy/page.tsx
  • apps/timo-web/app/[locale]/(main)/settings/withdrawal/_components/SettingsWithdrawalView.tsx
  • apps/timo-web/app/[locale]/(main)/settings/withdrawal/_containers/SettingsWithdrawalContainer.tsx
  • apps/timo-web/app/[locale]/(main)/settings/withdrawal/_queries/.gitkeep
  • apps/timo-web/app/[locale]/(main)/settings/withdrawal/_types/withdrawal-type.ts
  • apps/timo-web/app/[locale]/(main)/settings/withdrawal/page.tsx
  • apps/timo-web/constants/routes.ts
  • apps/timo-web/messages/en.json
  • apps/timo-web/messages/ko.json
  • packages/timo-design-system/src/components/button/tag-button/TagButton.stories.tsx
  • packages/timo-design-system/src/components/button/tag-button/TagButton.tsx
  • packages/timo-design-system/src/components/index.ts

Comment on lines +64 to +79
const handleConnectCalendar = () => {
if (profile.isCalendarConnected) {
// TODO: 실제 확인 모달로 교체
const confirmed = window.confirm("구글 캘린더 연동을 해제하시겠습니까?");
if (!confirmed) return;

// TODO: API - 연동 토큰 파기
console.log("구글 캘린더 연동 토큰을 파기합니다.");
setProfile((prev) => ({ ...prev, isCalendarConnected: false }));
return;
}

// TODO: Google 계정 인증 및 캘린더 접근 권한 동의 팝업 호출
console.log("Google Calendar 연동 인증 팝업을 호출합니다.");
setProfile((prev) => ({ ...prev, isCalendarConnected: true }));
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

임시 다이얼로그의 하드코딩된 한국어 문자열 i18n 처리 필요

window.confirm, window.prompt, window.alert에 하드코딩된 한국어 문자열이 사용되고 있습니다. PR 목표에서 임시 다이얼로그임을 명시하셨지만, 영어 사용자에게도 한국어가 표시되는 문제가 있습니다. 번역 키를 추가하고 useTranslations로 교체해주세요.

🔧 제안 수정안
   const handleConnectCalendar = () => {
     if (profile.isCalendarConnected) {
-      const confirmed = window.confirm("구글 캘린더 연동을 해제하시겠습니까?");
+      const confirmed = window.confirm(tSettings("profile.confirmDisconnect"));
       if (!confirmed) return;
   const handleAddTag = () => {
-    const newTag = window.prompt("추가할 태그를 입력해주세요")?.trim();
+    const newTag = window.prompt(tSettings("profile.promptAddTag"))?.trim();
     } catch {
-      window.alert("저장에 실패했습니다. 잠시 후 다시 시도해 주세요.");
+      window.alert(tSettings("profile.saveFailed"));
     } finally {

Also applies to: 86-93, 110-128

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/timo-web/app/`[locale]/(main)/settings/_containers/SettingsProfileContainer.tsx
around lines 64 - 79, The temporary dialog text in SettingsProfileContainer is
hardcoded in Korean, so replace the strings used by handleConnectCalendar and
the related dialog/toast helpers with translation keys via useTranslations. Add
the needed keys to the locale files, then read them in SettingsProfileContainer
instead of passing literal Korean text to window.confirm, window.prompt, and
window.alert so the same flow works for English users too.

Comment on lines 1 to 8
export default function SettingsPolicyPage() {
return <></>;
return (
<div className="flex flex-col gap-5 px-15 pt-7.5">
<h1 className="typo-headline-m-16 text-timo-gray-900">약관</h1>
<hr className="border-timo-gray-500" />
</div>
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

하드코딩된 "약관" 텍스트를 i18n 번역 키로 교체 필요

네비게이션에서는 tSettings("nav.policy")를 사용해 "약관"/"Terms & Policies"로 다국어 처리하고 있지만, 정책 페이지 본문은 하드코딩된 한국어 "약관"을 사용하고 있습니다. 영어 locale에서도 한국어가 표시되는 i18n 결함입니다. next-intl v4는 Server Component에서 useTranslations를 지원하므로 바로 적용 가능합니다.

🔧 제안 수정안
+import { useTranslations } from "next-intl";
+
 export default function SettingsPolicyPage() {
+  const t = useTranslations("Settings");
   return (
     <div className="flex flex-col gap-5 px-15 pt-7.5">
-      <h1 className="typo-headline-m-16 text-timo-gray-900">약관</h1>
+      <h1 className="typo-headline-m-16 text-timo-gray-900">{t("nav.policy")}</h1>
       <hr className="border-timo-gray-500" />
     </div>
   );
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default function SettingsPolicyPage() {
return <></>;
return (
<div className="flex flex-col gap-5 px-15 pt-7.5">
<h1 className="typo-headline-m-16 text-timo-gray-900">약관</h1>
<hr className="border-timo-gray-500" />
</div>
);
}
import { useTranslations } from "next-intl";
export default function SettingsPolicyPage() {
const t = useTranslations("Settings");
return (
<div className="flex flex-col gap-5 px-15 pt-7.5">
<h1 className="typo-headline-m-16 text-timo-gray-900">{t("nav.policy")}</h1>
<hr className="border-timo-gray-500" />
</div>
);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/timo-web/app/`[locale]/(main)/settings/policy/page.tsx around lines 1 -
8, The SettingsPolicyPage component is hardcoding the page title as Korean text,
so replace that literal in SettingsPolicyPage with a translated value from
next-intl instead of rendering "약관" directly. Use useTranslations in this Server
Component to read the existing policy/nav translation key (for example the same
settings namespace used by tSettings("nav.policy")) and render that value in the
h1 so the locale switches correctly for all languages.

Comment on lines +25 to +32
const handleWithdraw = () => {
// TODO: 실제 확인 모달로 교체
const confirmed = window.confirm(t("confirmMessage"));
if (!confirmed) return;

// TODO: API - 회원 탈퇴 및 데이터 영구 삭제
console.log("회원 탈퇴 API를 호출합니다.");
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial

TODO 항목 구현을 도울 수 있습니다.

window.confirm 임시 다이얼로그와 console.log 플레이스홀더에 대한 TODO가 명시되어 있습니다. PR 목표에서도 모달 UI가 준비되면 교체한다고 언급되어 있네요. 확인 모달 컴포넌트 구현이나 탈퇴 API 연동 로직 작성이 필요하시다면 도와드릴 수 있습니다. 새 이슈를 열어 추적하시겠습니까?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/timo-web/app/`[locale]/(main)/settings/withdrawal/_containers/SettingsWithdrawalContainer.tsx
around lines 25 - 32, Replace the temporary withdrawal flow in
SettingsWithdrawalContainer’s handleWithdraw with the real implementation
instead of the window.confirm placeholder and console.log stub. Hook the handler
up to the actual confirmation modal UI when available, and then call the
withdrawal API service for member deletion/data removal using the existing
handleWithdraw entry point so the TODOs are fully removed.

Comment thread packages/timo-design-system/src/components/button/tag-button/TagButton.tsx Outdated
@jjangminii jjangminii self-assigned this Jul 9, 2026
@jjangminii jjangminii added ⏰ Timo-web Timo 웹 서비스 ♠️ 정민 정민양 labels Jul 9, 2026
Comment on lines +9 to +36
export interface SettingsProfile {
name: string;
googleEmail: string;
isCalendarConnected: boolean;
tags: string[];
}

export interface SettingsTagItem {
id: string;
label: string;
isDefault: boolean;
}

export interface SettingsProfileLabels {
title: string;
profileSection: string;
calendarSection: string;
connect: string;
disconnect: string;
languageSection: string;
languageKorean: string;
languageEnglish: string;
tagsSection: string;
addTag: string;
logout: string;
save: string;
removeTag: (tag: string) => string;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

API 명세와 직접 연관되는 타입들은 zod 사용해서 런타임 타입 검증을 고려하면 좋을 것 같아요

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

동기화 되어야하는 값이 많아서 확실히 zod 공부해보고 고려햐봐야할 것 같네요 😢

Comment thread apps/timo-web/app/[locale]/(main)/settings/layout.tsx Outdated
Comment thread packages/timo-design-system/src/components/button/tag-button/TagButton.tsx Outdated
Comment thread packages/timo-design-system/src/components/index.ts Outdated
- 설정 프로필 폼 리팩터링을 위해 react-hook-form 패키지를 추가했습니다
- 컨테이너에서 직접 관리하던 draftLanguage·isDirty·isSaving useState를 제거하고 React Hook Form의 formState로 대체했습니다
- language·tags 변경을 setValue로 처리하고 저장 로직을 handleSubmit으로 감싸 컨테이너의 책임을 폼 상태 조율로 좁혔습니다

@ehye1 ehye1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

설정 페이지 깔끔하게 빠르게 잘 만들어주셨네요!!
나중에 모달이랑 태그 입력 조건 등등 추가해주시면 되겟당
수고하셨습니다!!🤗😙

- 어떤 소비처에서도 TagButtonVariant를 import하지 않아 불필요한 export를 제거했습니다
- (main) 라우트 그룹에 이미 main 랜드마크가 있어 중복되는 settings 레이아웃의 main을 section으로 변경했습니다
- 라우팅 훅과 상태 선언 사이에 빈 줄을 추가해 가독성을 정리했습니다

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/timo-web/app/[locale]/(main)/settings/_types/profile-type.ts (1)

1-8: 📐 Maintainability & Code Quality | 🔵 Trivial

type alias에 Types 접미사 누락

SettingsLanguageSettingsDefaultTagKey는 유니언 타입 alias이므로 컨벤션에 따라 Types 접미사가 필요합니다. As per coding guidelines, "type alias는 유니언·튜플·리터럴에만 사용, 접미사 Types"를 따라야 합니다.

♻️ 제안 수정안
-export type SettingsLanguage = "ko" | "en";
+export type SettingsLanguageTypes = "ko" | "en";

-export type SettingsDefaultTagKey =
+export type SettingsDefaultTagKeyTypes =
   | "assignment"
   | "work"
   | "exercise"
   | "dailyLife";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/timo-web/app/`[locale]/(main)/settings/_types/profile-type.ts around
lines 1 - 8, Rename the union type aliases SettingsLanguage and
SettingsDefaultTagKey to SettingsLanguageTypes and SettingsDefaultTagKeyTypes,
and update all references throughout the codebase to use the new names.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/timo-web/app/`[locale]/(main)/settings/_types/profile-type.ts:
- Around line 1-8: Rename the union type aliases SettingsLanguage and
SettingsDefaultTagKey to SettingsLanguageTypes and SettingsDefaultTagKeyTypes,
and update all references throughout the codebase to use the new names.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1facf3cf-b845-4890-8cad-2f898042bdcb

📥 Commits

Reviewing files that changed from the base of the PR and between d66f953 and 1705563.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • apps/timo-web/app/[locale]/(main)/settings/_containers/SettingsProfileContainer.tsx
  • apps/timo-web/app/[locale]/(main)/settings/_types/profile-type.ts
  • apps/timo-web/app/[locale]/(main)/settings/layout.tsx
  • apps/timo-web/package.json
  • packages/timo-design-system/src/components/index.ts
💤 Files with no reviewable changes (1)
  • packages/timo-design-system/src/components/index.ts

- TagButton이 태그 표시(정적·삭제가능)와 일반 클릭 액션(캘린더 연동·로그아웃 등)을 한 컴포넌트로 처리해 이름과 책임이 맞지 않아 분리했습니다
- TagChip은 태그 표시 전용으로 onRemove 유무만 분기하도록 단순화하고, PillButton은 onClick이 필수인 클릭 가능한 작은 버튼으로 정리했습니다
- TagButton 분리에 맞춰 태그 목록은 TagChip으로, 캘린더 연동·태그 추가·로그아웃 버튼은 PillButton으로 교체했습니다
- flex-col 부모의 기본 stretch로 버튼이 전체 너비를 차지해 Figma의 Hug 크기(111x44)와 어긋나 self-start를 추가했습니다
…to feat/web/122-settings-page-view

# Conflicts:
#	apps/timo-web/package.json
#	packages/timo-design-system/src/components/index.ts
@github-actions

Copy link
Copy Markdown

Storybook Preview

항목 링크
Storybook 열기
Chromatic 빌드 확인

마지막 업데이트: 2026-07-10 06:58 UTC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/timo-web/messages/ko.json (1)

62-62: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

한국어 띄어쓰기를 수정해 주세요.

더이상더 이상으로 표기해야 합니다.

수정 예시
-      "guideTitle": "더이상 Timo를 이용하지 않으시나요?",
+      "guideTitle": "더 이상 Timo를 이용하지 않으시나요?",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/timo-web/messages/ko.json` at line 62, In the Korean translation entry
"guideTitle", correct the spacing in the displayed text by changing "더이상" to "더
이상".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/timo-design-system/src/components/button/pill-button/PillButton.stories.tsx`:
- Around line 1-2: Update the imports in the PillButton Storybook file to use
the package’s configured absolute path aliases instead of the relative
"./PillButton" and "../../../icons" paths, preserving the existing symbols.

In
`@packages/timo-design-system/src/components/button/pill-button/PillButton.tsx`:
- Line 1: Update the cn import in PillButton.tsx to use the repository’s
configured absolute path alias instead of the relative "../../../lib" path,
following the existing TypeScript/React import convention.
- Around line 5-9: Rename the union type alias PillButtonVariant to
PillButtonVariantTypes and update all references, including the Record key in
PILL_BUTTON_VARIANT and any component props or exports using the original name.

In `@packages/timo-design-system/src/components/tag/tag-chip/TagChip.stories.tsx`:
- Line 1: TagChip.stories.tsx의 TagChip import를 상대 경로 "./TagChip"에서 프로젝트에 정의된 절대
경로 alias import로 변경하세요.

In `@packages/timo-design-system/src/components/tag/tag-chip/TagChip.tsx`:
- Around line 1-2: Update the imports in TagChip.tsx to use the repository’s
configured absolute package aliases instead of the relative paths
"../../../icons" and "../../../lib", preserving the existing DeleteIcon and cn
symbols.
- Around line 8-9: TagChip의 삭제 버튼이 접근성 이름 없이 렌더링되지 않도록 onRemove와 removeLabel의
타입을 함께 조정하세요. onRemove가 제공되는 경우 removeLabel을 필수로 요구하고, TagChip 내부 삭제 버튼의
aria-label에 해당 값을 전달하며 관련 타입 정의와 사용처도 업데이트하세요.

---

Outside diff comments:
In `@apps/timo-web/messages/ko.json`:
- Line 62: In the Korean translation entry "guideTitle", correct the spacing in
the displayed text by changing "더이상" to "더 이상".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ebc52247-d46a-448c-9a52-df5fffb15caa

📥 Commits

Reviewing files that changed from the base of the PR and between 1705563 and 5a79e43.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • apps/timo-web/app/[locale]/(main)/settings/_components/SettingsProfileForm.tsx
  • apps/timo-web/app/[locale]/(main)/settings/withdrawal/_components/SettingsWithdrawalView.tsx
  • apps/timo-web/messages/en.json
  • apps/timo-web/messages/ko.json
  • apps/timo-web/package.json
  • packages/timo-design-system/src/components/button/pill-button/PillButton.stories.tsx
  • packages/timo-design-system/src/components/button/pill-button/PillButton.tsx
  • packages/timo-design-system/src/components/index.ts
  • packages/timo-design-system/src/components/tag/tag-chip/TagChip.stories.tsx
  • packages/timo-design-system/src/components/tag/tag-chip/TagChip.tsx

Comment on lines +1 to +2
import { PillButton } from "./PillButton";
import { PlusGrayIcon } from "../../../icons";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Storybook import도 절대 경로로 통일해 주세요.

./PillButton../../../icons는 TypeScript/React 파일의 상대 경로 import 규칙을 위반합니다. 패키지에서 사용하는 절대 경로 alias로 변경해 주세요.

As per path instructions: TypeScript/React 파일은 상대 경로보다 절대 경로 import를 사용해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/timo-design-system/src/components/button/pill-button/PillButton.stories.tsx`
around lines 1 - 2, Update the imports in the PillButton Storybook file to use
the package’s configured absolute path aliases instead of the relative
"./PillButton" and "../../../icons" paths, preserving the existing symbols.

Source: Path instructions

@@ -0,0 +1,39 @@
import { cn } from "../../../lib";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

상대 경로 import를 절대 경로로 변경해 주세요.

../../../lib는 저장소의 TypeScript/React import 규칙을 위반합니다. 패키지에서 사용하는 절대 경로 alias로 cn을 가져오면 디렉터리 구조 변경에도 더 안전합니다. 참고: https://www.typescriptlang.org/docs/handbook/module-resolution.html

As per path instructions: TypeScript/React 파일은 상대 경로보다 절대 경로 import를 사용해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/timo-design-system/src/components/button/pill-button/PillButton.tsx`
at line 1, Update the cn import in PillButton.tsx to use the repository’s
configured absolute path alias instead of the relative "../../../lib" path,
following the existing TypeScript/React import convention.

Source: Path instructions

Comment on lines +5 to +9
export type PillButtonVariant = "gray" | "blue";

const PILL_BUTTON_VARIANT: Record<PillButtonVariant, string> = {
gray: "bg-timo-gray-300 text-timo-gray-900",
blue: "bg-timo-blue-300 text-white",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

유니언 타입 alias 이름에 Types 접미사를 사용해 주세요.

PillButtonVariant는 유니언 타입 alias이므로 PillButtonVariantTypes로 이름을 변경하고 Record 선언도 함께 갱신해야 합니다.

As per path instructions: 유니언·튜플·리터럴을 제외한 타입 alias에는 Types 접미사 규칙을 적용하며, 이 프로젝트의 해당 타입도 일관된 이름을 사용해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/timo-design-system/src/components/button/pill-button/PillButton.tsx`
around lines 5 - 9, Rename the union type alias PillButtonVariant to
PillButtonVariantTypes and update all references, including the Record key in
PILL_BUTTON_VARIANT and any component props or exports using the original name.

Source: Path instructions

@@ -0,0 +1,44 @@
import { TagChip } from "./TagChip";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Storybook import를 절대 경로로 변경해 주세요.

./TagChip는 TypeScript/React 파일의 상대 경로 import 규칙을 위반합니다. 프로젝트의 절대 경로 alias를 사용해 주세요.

As per path instructions: TypeScript/React 파일은 상대 경로보다 절대 경로 import를 사용해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/timo-design-system/src/components/tag/tag-chip/TagChip.stories.tsx`
at line 1, TagChip.stories.tsx의 TagChip import를 상대 경로 "./TagChip"에서 프로젝트에 정의된 절대
경로 alias import로 변경하세요.

Source: Path instructions

Comment on lines +1 to +2
import { DeleteIcon } from "../../../icons";
import { cn } from "../../../lib";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

상대 경로 import를 절대 경로로 변경해 주세요.

../../../icons../../../lib는 저장소의 TypeScript/React import 규칙을 위반합니다. 패키지 alias를 사용해 import 경로를 고정해 주세요.

As per path instructions: TypeScript/React 파일은 상대 경로보다 절대 경로 import를 사용해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/timo-design-system/src/components/tag/tag-chip/TagChip.tsx` around
lines 1 - 2, Update the imports in TagChip.tsx to use the repository’s
configured absolute package aliases instead of the relative paths
"../../../icons" and "../../../lib", preserving the existing DeleteIcon and cn
symbols.

Source: Path instructions

Comment on lines +8 to +9
onRemove?: () => void;
removeLabel?: string;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

삭제 버튼의 접근성 이름을 타입 수준에서 보장해 주세요.

onRemove가 있으면 아이콘 전용 버튼이 렌더링되지만, removeLabel은 선택 사항이라 aria-label={undefined}인 버튼이 만들어질 수 있습니다. 삭제 가능한 상태에서는 removeLabel을 필수로 만들거나, 항상 현지화된 기본 라벨을 제공해 주세요. 참고: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label

As per path instructions: 텍스트 없는 버튼에는 aria-label이 필수입니다.

Also applies to: 24-30

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/timo-design-system/src/components/tag/tag-chip/TagChip.tsx` around
lines 8 - 9, TagChip의 삭제 버튼이 접근성 이름 없이 렌더링되지 않도록 onRemove와 removeLabel의 타입을 함께
조정하세요. onRemove가 제공되는 경우 removeLabel을 필수로 요구하고, TagChip 내부 삭제 버튼의 aria-label에 해당
값을 전달하며 관련 타입 정의와 사용처도 업데이트하세요.

Source: Path instructions

Comment on lines +55 to +69
const labels: SettingsProfileLabels = {
title: tSettings("profile.title"),
profileSection: tSettings("profile.profileSection"),
calendarSection: tSettings("profile.calendarSection"),
connect: tSettings("profile.connect"),
disconnect: tSettings("profile.disconnect"),
languageSection: tSettings("profile.languageSection"),
languageKorean: tSettings("profile.languageKorean"),
languageEnglish: tSettings("profile.languageEnglish"),
tagsSection: tSettings("profile.tagsSection"),
addTag: tSettings("profile.addTag"),
logout: tSettings("profile.logout"),
save: tSettings("profile.save"),
removeTag: (tag: string) => tSettings("profile.removeTag", { tag }),
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

이 다국어 매핑값들 객체로 한번에 추출해서, 컨테이너에서는 구조 분해 할당으로 간단하게 로직을 처리할 수 있을 것 같아요!

@yumin-kim2 yumin-kim2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

전체적으로 컨테이너와 뷰 컴포넌트의 역할이 잘 나뉘어 있어서 읽기 좋았습니다. 특히 개인정보 설정에서 언어/태그 변경값을 react-hook-form으로 관리한 덕분에 변경 여부와 저장 상태를 직접 상태로 하나씩 관리하지 않아도 되어 코드가 깔끔해진 것 같아요! (덕분에 react-hook-form 공부도 했네요✨)

작은 코멘트 남겼는데 확인해주세요! 수고하셨씁니다아아

const handleAddTag = () => {
// TODO: 실제 태그 추가 모달로 교체
const newTag = window.prompt("추가할 태그를 입력해주세요")?.trim();
if (!newTag || tags.includes(newTag)) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

화면설계서에 "1~10자의 중복 없는 신규 태그명 입력 시 활성화 상태로 클릭 가능" 이라는 조건이 있는데 현재는 중복 검사만 있고 길이 제한 로직이 없는 것 같습니다 확인 부탁드릴게용🙇‍♀️

export const SettingsWithdrawalContainer = () => {
const t = useTranslations("Settings.withdrawal");

const labels: SettingsWithdrawalLabels = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

탈퇴 화면 문구를 전부 i18n으로 관리해서 한국어/영어 확장에 대응한 점이 좋네용 👍

removeTag: (tag: string) => tSettings("profile.removeTag", { tag }),
};

const handleConnectCalendar = () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

handleConnectCalendar가 실제로는 연동과 연동 해제를 모두 처리하고 있어서, handleToggleCalendarConnection처럼 연동/해제를 모두 포함하는 동작이 드러나는 이름도 고려해볼 수 있을 것 같습니다! 아니면 함수명이 너무 길어져서 안 좋을까요?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⌚ Timo-Design-system Timo 디자인 시스템 ⏰ Timo-web Timo 웹 서비스 ♠️ 정민 정민양

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 설정 페이지 뷰 구현

4 participants