Skip to content

Conversation

@Yejiin21
Copy link
Contributor

@Yejiin21 Yejiin21 commented Jul 4, 2025

마이페이지

스크린샷 2025-07-04 오후 12 08 00

마이페이지 - 문의하기

스크린샷 2025-07-04 오후 12 08 04

메일 클릭시 자동으로 이메일 링크로 연결

스크린샷 2025-07-04 오후 12 08 22

Summary by CodeRabbit

  • New Features

    • 북마크된 이벤트 목록을 보여주는 BookmarkList 컴포넌트가 추가되었습니다.
    • 사용자 프로필 정보를 조회 및 수정할 수 있는 ProfileInfo 컴포넌트가 도입되었습니다.
    • 버튼에 'full' 사이즈 옵션이 추가되어 전체 너비 버튼 사용이 가능합니다.
    • 텍스트 필드에서 에러 메시지 위치를 하단 또는 우측으로 선택할 수 있는 옵션이 추가되었습니다.
  • UI/스타일

    • 마이페이지 UI가 개편되어 프로필, 북마크, 티켓 정보, 문의, 로그아웃 등으로 구성되었습니다.
    • 마이페이지 배경색이 새롭게 적용되었습니다.
    • 레이아웃 컨테이너에 테두리가 추가되었습니다.
  • 버그 수정 및 개선

    • 일부 컴포넌트의 스타일 및 구조가 개선되었습니다.
    • 프로필 이름 표시 방식이 통일된 유틸 함수로 변경되었습니다.
  • 기타

    • 신규 라이브러리(classnames)가 추가되었습니다.
    • 이벤트 공유 모달 내 이벤트 정보 표시가 개선되었습니다.

@Yejiin21 Yejiin21 requested review from hyeeuncho and xaexunxang July 4, 2025 03:10
@Yejiin21 Yejiin21 self-assigned this Jul 4, 2025
@Yejiin21 Yejiin21 added the 🔧 Feature 기능 구현 label Jul 4, 2025
@Yejiin21 Yejiin21 linked an issue Jul 4, 2025 that may be closed by this pull request
2 tasks
@coderabbitai
Copy link

coderabbitai bot commented Jul 4, 2025

## Walkthrough

이번 변경에서는 디자인 시스템의 버튼과 입력 필드에 새로운 옵션이 추가되고, 마이페이지(MyPage) 관련 UI가 대폭 리팩토링되었습니다. 여러 신규 컴포넌트가 도입되었으며, Tailwind 설정 및 패키지 의존성도 일부 추가되었습니다.

## Changes

| 파일/경로 요약 | 변경 내용 요약 |
|---|---|
| design-system/stories/buttons/TertiaryButton.stories.tsx, design-system/ui/buttons/TertiaryButton.tsx | TertiaryButton에 'full' 사이즈 옵션 및 관련 스토리 추가 |
| design-system/ui/textFields/DefaultTextField.tsx | errorPosition prop 추가 및 에러 메시지 위치/스타일 개선 |
| package.json | @types/classnames 의존성 추가 |
| src/app/Layout.tsx | 내부 컨테이너에 border 스타일 추가 |
| src/entities/user/ui/BookmarkList.tsx, src/entities/user/ui/EventInfo.tsx, src/entities/user/ui/ProfileInfo.tsx | BookmarkList, EventInfo, ProfileInfo 신규 컴포넌트 도입 |
| src/features/event/ui/ShareEventModal.tsx | 이미지/타이틀 렌더링을 EventInfo 컴포넌트로 대체 |
| src/pages/event/ui/EventDetailsPage.tsx | JSX 인덴트 및 key 변경, 로직 변화 없음 |
| src/pages/menu/ui/MyPage.tsx | MyPage 대규모 리팩토링: 데이터 fetch/폼 제거, ProfileInfo·BookmarkList·정적 UI로 대체 |
| src/shared/ui/FloatingButton.tsx | 파라미터 구조 단일화 및 불필요한 콤마 제거 (동작 변화 없음) |
| tailwind.config.js | myPageBg 색상 추가 (#F9FAFB) |
| src/pages/event/ui/AllEventsPage.tsx, src/pages/event/ui/CategoryPage.tsx, src/pages/home/ui/MainPage.tsx, src/shared/lib/formatProfileName.ts | 사용자 이름 표시를 위한 formatProfilName 유틸 함수 도입 및 적용 |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant MyPage
    participant ProfileInfo
    participant BookmarkList

    User->>MyPage: 마이페이지 접속
    MyPage->>ProfileInfo: 사용자 정보 표시/수정 컴포넌트 렌더링
    MyPage->>BookmarkList: 북마크 이벤트 리스트 컴포넌트 렌더링
    User->>ProfileInfo: 정보 수정 시도
    ProfileInfo->>ProfileInfo: 폼 제출 및 유효성 검사, 업데이트
    User->>BookmarkList: 북마크 클릭
    BookmarkList->>User: 이벤트 상세 페이지로 이동

Possibly related PRs

  • GoTogether-Inc/frontend#104: MyPage.tsx에서 API 연동과 동적 유저 데이터 처리 추가, 이번 PR과 동일 파일의 반대 방향 변경(동적→정적)과 직접적으로 연관됨.

Suggested labels

🪄 Refactoring, 💖 Style

Poem

🐰
버튼이 커졌네, 'full'로 한가득
프로필도 북마크도 새로워진 모습
마이페이지는 깔끔하게 변신!
토끼는 오늘도 코드를 다듬지
border와 색상, 스타일도 추가
변화의 발자국, 깡총깡총 남긴다
🥕✨


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpETZWaCrKNwSPbABsvkCiQBHbGlcSHFcLzpIACIlRHgiDC5ACc7AF3HADOXUwAHJyEAfZcAUPsAazsBHoejIAHc0ZAcBZnUaejlIbERKSABNEiF4eAwAJgBGdGRbSAxHATbBod6w2A8AcXxofFJceYowAEkMBgB6ADMKfAwaDHp/bnx4ghcNGHnGWExSZAP8Bhb+LHWPOISsJh6NxsAIvEgEBgiPwDnMPNE0pksmUABQAWXkVjQpAAlPZROITjC4ehuNxwQxqPATho3I9sNxaNQPL0GF5sHESfBmOSSGxTlSifhYb9IBjrNiWadKAc0AwSAAaYb2WD4cpYWai3j4CTwJT0RAMfxkRCq3CIe5bUJoLyIfAKKQUZCi6KADm7ABrjgA1VwAMdaiAMInXBy0IAVUQeJqrTE1Kw5XUkLFmMlSrj63QCgo/kQV3OvWh/0SkC8aFk+DwkCUzBOiFwVAaKB+j25kotRgAgrRaOoYzavLIlVrvL5/EEQg3a4psPK3thdoSMDb1PJyhsPGz4AwANZ577oLB87S+NCdrPINB4FhUyk+eTgjCb5320UtSgAcmQB/gvnX7CVsoYX7qFSUIVvA/hiJAn7fiwzCzhugoYPccCoJMzy6vgfCoF+7I1nWUSao8By9Da9hGiQJpmkqppqjuopQUWvSbuOyjRjSRgAPKOr2A6PKMZDPLs0gki+mHShQ/4eECzStHwJAAB7cJQ8BkPKxKiuKWKkPirFYE0x5diB5DlBW0gApBkT8uae70L0NBUNGUiQcwh4Mfeea0gY+jGOAUBkPQwo4AQxBkMo9ZMKw7BcLw/DCASkhCU0TBKFQqjqFoOheSYUDIcgqCYIFhCkOQeH0OFllcFQxkOE4LiQIlijKKlmjaLoYCGN5pgGAWGBgIgsg1nyew1hhymIHsAh4AQGBjdAlDiM4sgAEKTTSw0UKNGjmnJHAGNEe0GBYkBtlswXFcyBqOM5tUBQwAmvHSHhrbIAj4PgTFMBgRFENgdYxpA7x8KKAAGs0UPNLjLbgU1AwoPInOwFRVM0jLnWE9qsuySjpkZdUrVg8QAF4ePg3DzkqQPRAcQ7REDSEILlGASPgXhSPQ+k7hTVM+DTaMkkDhMkDDH0Tr4JPzgzfPOEQ0CyIpiAw0oREYN2NJHZ2KsLjeSpoGMJBVbc8gLmw9BAwAYkOMOVAzE60FOdApggt34lZooTVDJzvpA/PwETMPatwvOc9TMNSS+zqPMWky+BTgAANYApeOQIADguQIAIT2AD1LPOprAJJMF4GFe9E3CMTzUm4LLHgU27U00/cABy9r4L8fC3S8QkEJBclIOIIFraN/DN4Gxy2hUlAeM5SgeeYlhtl4dkIY+JJKGyzjz8S8lXGDUT5yCYIbpBpzdtIRhQB2+q68Z68YfWT1cGbFtqeXXsAMoGzDsxA91vX9TQzBDbco3jTxjNOa8AFqQymhoXu0hNqIDkpbeM6AKBEGQEDAA3kWFQJAvBcFfPHJOqc06vgHOXHBVcPZKlzhhHBRd7xEPsD7EgOCuZeFfJAAAvkDXa+1PKdU/n1Aav9sDwEAe7aaexQbgyWnjGB20uHRAOtPE6RVQpRGqldeQN07pHwMO4L2EjQEQzxlYY43B5bMXEnKDwVsO5nDPu3DGHJJLn3oUTfgpM/pA1fMw18Ic85QniFjOincawc3fM5HwPjyavmNvARwkTrJe1fMWJBJAfEuOgZAAMmZpA5gMkQPs2tnF+ifk/RgxZEDVFrDuax+kojt2BgLP05TWhmOcmSHcAM+ZeKHGkgWVFFIAQOLIDpQ4Kh6jTCiIG5QwDMKBjiJUjpxDXh4OzECkzuCyDAAMOZ2tzjpkQOE3wNA5KhAFpASZxzcC9WYHMumeV1bzn3ioSI4cK76LAXjIWLAcwI3bg4MkV90zMLAHGWgaYyH4zLpEMZaYPrxAGqcFZ6sQJSXeIigWk8FFHVnqFGMC9RRL2SavAKl9N7+T4DvCk+9wijWPpAEMKN6y2RlJYvRICPmiOMSTMx78+Hf0GkIkRU1gFgwMVI0RMiYZ6WRdCTx3iYb1MeN7X2zRlZEjLopLgkADCQEgKbY4zAvYCxwQc3srCAA+kBol0FicwC1VrkmkFfAAbhhtq3VKwjUMJNYc+11quxxMgJapJUtUlBqtd411cjj68NMokL+Ai9iCsuabZSXhaBjQACIkFlN4XAs0TmpqwbQGRO09ryMOsdU6KiLo1Q0bCFuUJtFtiwGLHsvh/Ze0oMcCgVhrga0tkjWp9BFUV2zbm2eBbcBFvTVy0xb8xISRhdnK4FT4Bgg8BIG0wQUGvheu7O1MN86ePWkQWAuB4mK3PLPWi9pPH7oIIeumUoQShCwXyBGqAMBqgqFQMk+Fpp6icf4Ys4gpB9h4P2+cURhbaGKl7YAXYJB6AVfaMgzzJICDtOyGgkGbgxh3AFOimZ85sAqZKCo8wsBA27RhPt+GThv13ae89Pj7gAHUqNdpI72qDMYmOJJYxekOez8q0b4GRxAFH5Jd0QDxDw4nICSYo6gfw5xR4jqfI8ITakmwYFfVwIkcRNwEADoaY000UChDylh5meAsHyFXRrKIiz4I3kYOwDTvNRQ6YCcTEUenX27P8lgKsahoXmfIpZ9QKBkBdmzMWWQUQo4/tFL0V9lpYQ0Z4/RgdsWxiN0EwkVjQN5OQR40p6QUmtKqb8l5lLxk0v6fLEjSYAMPBu2XcjJk18oXuQeC+vAnsayyDvNCGptAhAtHrCieYxXcBKm4KsogSoXoUGSn4Y8sS5P/UDOkvEpdHiwd6G0XCU5cA/SsUjKsXYiJ1PtP8jeoRRQ40S2WTQYpej5wBs5KGO4pLZjlP9yb03LLIHKKPJTx4PCjpMkGL8GCo4JOO/BpDrYjBYpnnPcW3nHiEpXjjklCkr5bwpaCKl7BD6IDpafLe7iTgkU7dlntuX5wAH5SGN0fX6oTaT7GLtZUDcd1783yWnWm2gc6eXUb5Ym5NYuZ0Zr2MLvNU7FeSujTwsARgltbklBoIQdokjRsrUokKJV7CXQWsSRt90dFHa0egTsryVl660tEAAAhq6Qexl4VKNtIMojp4hEmiAAPT6BoAAzBoAALGUWHsQSASGzYpdTuxRplCjI8ojSrdebn14bxj/0vwkDrg3JuJk09KAz9IKiRp4Ckx2/nD6X0foIWpetISzgx6KHgHd8lfg+Q6joB5StOLfrVlx38UQRLCewlJfWbe5O96U/ENo+u5BaTlpjdrgwiAKD7DQGSPYAAZEs73S0m8UdWi3ajreaNbtT+3Hg3vlnCj804ntejwZR20JDiMyAN2/eykmmDYbIji6Ya2G2WcOczSQkQM0BbQSBmwRAVAmyfQAADJgbTA8PchmumLqPEBunVBhBts4GWHsqKCuOoB1nKJuGgZQaVIGHBm0OsNQL+sfi7s5LMMLAjFJE9iREhuXvwJXmdmIO3qLHwFTHOO2k8E/iPP4FDhPFPNitjnitPiZMvJPpZkTk9qTp4LvAwNSlTkYJviQJrhAHvgfvsGvgAiJEmsIotK9JuFdJuKfl3FfjvqbrfqjPftdA2los/m2M4jYCQMGP9LODpCRB/vDIikDM4W9G4R4TWAJrZMcLbPKGAfFuSCWOmOCDWMSC9Ekc4JuFEMnuwBaJAFaNJN3owNNiwJAKqG9F7C+Ika4aUWYu3AcCQLgE7MUR0RQExD1jrFJEDC+LXGgLqEQMyDDEcI0UDP4MGGAMcPZpsLQCwHMfnAuNMQhM+rDJ/qclfC7gMW4TIPIL8GBF7HqAusMPKLmCBGQW0FJOCHUC7HjkgLkRcVph4ERE6M9uUGhlIKcFUQAKJyjZwVGIq1bqb+D0AtD/bUagnAm4A7DvBfJwzkCnBUSqhxggR0QomewCCYDwbNikADjqCRDBa7YUC/a9bOChA9Zl6ZIUjbgor7goljBTEJDMgLzqBxa9GHhRBLakCZYFakElFDEfjBILbpi5HyiqjpptDKY1bVC4mIRqxdjzi9j9jpjrh64kGXKuRMSoDai6h2L2g7E8m4aw7MISmDFMQFGhAinMm6KxFYnWaVKjZRCwF4CARlxlJVAtI0kYKlh4D9JA5QjUkaqrB/qwCyCYrj7qFT6w7446HIB6Ek6D6Uqr4Hzr7P5QC1x6yQBhEREyHRHQSYkIwJEuHJFdwKyz495sx7KL5RBIxXp5oNhGqH57B2E+4OGCrtF1k1iSrb7cJWFGA2G9l5n2EySOF7DInsBon4BeH7Q+HKJ35W4BHyFNrBGhHhEQTlnamVmHFeyLmnDLlpGnAZF2z0CwHe7AgmIClKzJYXFKrnmomfT4BS4Lp2QST7Hun8EMDyhN57iQSclkkeAhg2Cn6FLhBUlgVtoM6+BMn2BVJRkJL5RIWaxlIbhMQCS0CRDSFRHziWihBqbJRni4UGnQp/58CwE6yqjrQEwsHuaLiJBRBv6hAo60SPBQnWbORaRSQ6yubLI1j0G6YKacnwWSR7JMn7EyVhBi75YjaRBgG1hRHMhdZYLgimJYSwgxYj7iR5zlBVG6KoWoA5GJYAb7KHKUBKhoF5FoqhANYkgyX7GQVNFIxERyRRBdj8gh6WawGrHqbMEUDFRnh7JZg5jxCOSEwdKkY2qOCkQWZmV8UHxKF0W1FUWfBOjbz4DMp8CqUw7oy5iUi4aFXBiSBLiUZkBgVAwnBNJ4UwwEVEX5ZmlAYloDYHFxGekdz6Fswu4dmzz9VXyJnTwT6rypmNnplrzE5kr9yGEU4znaInydgAZ/mC4fnLk/ldb+wgLSC3z8VbCCUkAhgUDYJoXrRQilZewyVcC4R5i3UfzMgc5XVPXkyNWslvUoh4gAC8egkATMNxXZ/MPZfZY0A5wi21X5Gua1Z8w1b6819YpZh5JFchgF8RMN6Je1T5YQ5cg1Z5KJO1T5txYNthK1kNc5gq2NK5W0nCO+Wuk54NlNSa1NwiXKREkQy5q5FaN+G5fhW59aO5duIROMqNoQR5GN3yvVXsnNpel5+W6Rk4WRvMVleRUkNqoQIkPAxwXNUoP2ex1R2twZixB5VyzRm4MyGENyXWQMLFtAYR2GjoWx0hNtQNi4PWf0xJrQIWcpcJOaJ2Bot0B4AFMtHp/0vRIdyAOtIxQNoCepDRhqltrRrQYYlAitocjKQksd1AOs6wqxZ6qdZ1MkDKTJuBNRzkC4rwYFWtO44lNpT4qw+SHWvREOdV6t8gmtWpSmDU6OnGdV36b6WpeYZWmNpyuJLuIknsAeCS3Aqo5AYwEwzxfiyCQG/twopejAYEbIslbMuMoivMnmskPdN2zJOwkEp9DUSoMWFFlAVFP2XWwsQ8alDYr6bw2xaAbAc9C9Hg4wzAkwFA2sZIfYO4898MS9ADbQhtf2jxGozW3FWi9w7EWAj9NQdQa6JwN9z2p6pAToYFDIqFsEQYjy95jwOMIxSorV9dU4045x3WwE0Ioo+SggJE54aYa0ioQ+PRfRkI0IOtvQ7w1JMm3c0IWtvdSg1J1DIE4m9DNoIC+J9IMkHkp++AW27J9AimDdQkts11+YedkdvD/2ShrVPpCC8QPI0KKpGSuiIYWw2VJk8QhY/CP8PVHpH9fAEKO2Rpd26aO2AhetW9nd1Jx+5IfcqlCVfAXFCS0V1Y8U5AFSY+E1yZlm012hxKC+yNBhOZxhENdKRZxkEtbjCMrZtAt88t3NX5ZNU5ENbNlA85FTJAPN9NlhnUU5PR1Al2Y0/F85T8zw/gH5aIigNovNmOZuZ018QtNuQRD0ItHglwxY04JI68FIt9dWejkl4Fn6p1CSilWcBEHgfTPegzwzJ5stDF9CUI0K3IA1xTiKAeJstNuBxiye1ILQBSJIN2QhYEBIEGd9cJ9VwA3IRAKG5kH6iKnSBJ2zFGwlCGgOGAoL76lkIZULiK7lR0BwdkOcWi8mrQYQgJYLYOiCCmuwXB3gqMvQfmfMTzdzspNBTs4EJA8UKCx1p151XgImJsMlIcyA/sVR9cohGwRYqwG4So/FXl5wRFzefAdjhLlRXZooXzR4ShwBA+STahuKKZPxWhc+GhmZC1y+RhJh+Z+T9otubcaGWT2ZK+uTeZ8gaZq8EOKr0OY58iTN++PZLp3TKJ85H52a8OtomkZeW0Zaa5/N5ugtda0zT+sz5rDDNALu/zhGAW8IgAALWAAUHZAIAIOdgANguohhGgZRAeH3jhjaSPIHNE3sD+uHiIBBsYmnlNALORlMNKptJzHo0ezIBlHyDzGGqijODoENhKBySaF3ibiezQWwX7wOAbM6xVhKHiUkGhzKyjiQDdshkHnZxjtWZ8j7ErMbgxYarJt8y9DDt+wrxsBYsVtAxtuMC9jElbj5b+BVisz7EABST8AAGkO+wB3vclNgNGAZML3UoUoCQOSIbCEPbAfSSEZb2FdedpdsjicCPchUPrCTuHnEQHvM+3Bqqua11QK43EK1LWhy3oPMzP9CZXM2eEocrZkaPqoVjpq6k9qw6/PqNQa2Tka3kwYOYa67vszfsF63sPyNgPORiEG6M+uRG5M1G4/rubM5JxRuPYAdw8GBhPdkPi+5JD4LUXwHHTw7dKPTScnUCGNgsp7QhNSYQ1pVhxuPsbwK82WMgMHn9C+PQJbQvEZ9nAI1+UqFXRRmgyQ1YggksWIGAJbdbbSZZ+CBZQg/43srZ7hrnUGF1sQx3l5zfbsJjJh2o3kgkloyF2lVBfY05+hO8/a58dZZo1qRhiXsWh41yd/QIb/ZA4A11lunFx3rI5hfYFMR1tIrMzjG50SFgtyMRAm+gHp4/elngDtl13qNZwksl2PKIAJEgMwFUTsANMeNg+h5RWhVeNYIE5U+8AkkOaUSkdxeHfK50rHYKV+JFY0LWZ0WRU7gQTrPqQXiQdnn9GO7ep4Ifs8L7WEHhb0Q2DAzGIUrnMWHpSQW6F6L6Ocr0EEGBLIBGHFESAxfuDwb4Nu50o9lfCE8K0QO9gfVNHMBwVaTMVN+3DrFh+T6sTQPsdEwDn1iikoat3eQgjjFlWjhGQBBhbCzQbhg+wwSFZ5+EclPsQ+o0cSXwLh5S/cDPB2v4BV8gHnOoytuVj2hK4RSZ1nahT0XQOL8S9pyPiWkx5NTjmk7q1Pvq0vtx8tTSqtZAAK+awvKU4tTk8a/azNfPM6jnLd/Ecp6QDDEr5ZjrIjZx6EGQ49F/Y9ACJ0/4AJ+61OaaE2fOabFr6I+AjSCG9fkdOMzWpbvJ4ETGy/nMwoNNMzEt3T48EtlQJe//iEBQIhxs7nhXDn2o3n58pEbIWh6p72+mLBDemAHeL8TbRwbZPaDrPEFcyQBPydqZxwVnOTzaHZLxR4E34n3ZBmYDHNoDOXFUafBrDqXBVQIBCBGVKMZi2wUqn7ogJMWwCHEgo4J+o2BXE/y/9IO24P1gGvC+BasOnLqu4CUI95xSnvTQuPU9j2cGAq2EgGhGpBANFqH7b9uIQuyp8McmOG3hoTt4E49WmTW5oaxd6mE+O8MVpnvgDZ4kS0reBIAbkQChs+axfXwnJ3UTRtFOBgMWsWUoR8AHmXsZgLICDaLQiA8CNMKKHmAjsuuwQL2GYFNgABOU2G2FNiLRB0Z4daupUf7MwMIZiP7kKBTYwBDwtAzJCUhr5t4dCdyZAHwKVrShQqKLR4OL0YKzh/Ihg6IBpElBZ4seGpIjpXmgHtx4BFCCjr4AOAmUlQ+cRTNI3GyQ5x4Zea3ik3xR44A+HHb3qQNzKu8CympNss4hsH7UwY8gG9sIMlCiCcE8gpQSoMWh85tWQMPgWYkEAiAIIFbaAMYNPamDSk9A76DoRLzQogYNA09hoA6GMDaYVAoTnsBE49NBUqvD8rW31yF9vC4bCZqoimYKc7cbpR3E2yWZNZJ+luLDOhTEYnJ7IOeQwdPWQCz0UQ5XN5ogAgxAwA8bOSBBSBIAogBgSoKPHiHNTBofEeIC5kAN5g6wcYfpcEAGVI7UYYGFTX/iiFnrvCrUr4HEG/DhgLUR+8/fppxXXRUA7geBIAn3juzIBcSi8ariWGFKnc/6iffLMlHij0BIWSqRpn6B3qRB62stCtvMGhwUBPYOmPgoihXB1VnwMkfLFh1IA2QNSuiLMKEC760s4BIrYwuz3b4SElCkffDloit4Y4kyLHRITPnSYpCrWPvG1sa1pSeR3eZrIIkfU1FpDbW4Qf3uqI0LvwphKJGYaKXppp8JyHrYTi2F7I+tBUfoZkGTxcBSc5hYbVgQLXYEP4K+XAtYa3CHzyk6iXYcCKclBCPUZGBwqqkSBH7AwA8MMLdOtHq6TJbh9wjcI8OeGQBXhQaD4XMi6xfd4O9PZxACJqrAivYoI07uCMhEfDYRvMAMTDg+IJY8is9JbBUi07AxqRtIwWLSysESMQCQkXEVqCJHNcWQHjOkslhzSacDuSkDCvcVrCLgCY2/VfrA2hDwCFWTYeEfWCBh1jN6XgX/v/x0gNhdurg+wKs0UaPQ9hDYSfuq2Y6zUCBs1R3tk21G8dCyBohQu3FSHO90hNVdjhoSdZjwXWIwp0WMJdGqg2AEnODD6NgTMCxmbApYeXxo6xtDR9HO2GBRuaApRRh46frgDBGJ8YYVYoER20BBRVwOizNsTv3V6XCHxK/SMPeLFyHC/oook4VOPOQ3DE+dwq4bmKeEvDYRXwhBGWL07twCJtJagMRLYAQiSRUI18DCMthcYk2t4uWkSJpGH46RQ47qg1QwB+gtELVcztA3zjAwn44RYHmrglzqC5mFIg1LXR5ABkwQHwd6CwV6D/Z7AuuEqg5NJjyBnJj7dfi1k8mWIHYG4bOHlCUxfY3aUkrcU7gA64BLIKvB5O2g+bAwf+JE9AFDHWhuxiYX/L2D30Yb58MA9IiOtYgI7/R7JC/FupACCCNwLWFYMsCQVqkJttY4IRINUgQSigkod470iIWgGgTlC3k0UDuPI7XlKOoQn9JMFLBUF5geLY8PFLBzjUNWL4tjskKIGx8PxPHSmmYXhgOi2mPZTPnCT2DggBAhwQiY01/4wIkJMnRYbWg4ErDm0lY8QICJ7YUTax50+sRlKwhjSGOI6Z4M9jQBlEqKVU6FNhRIhxjoQu/FvnwB4mv8xSTWV9F7FTH5YXBgdcgIPllC2hdSooGsf4CwFR9cevk96lCGQZNw4wrQfbnjJ+hR8dhEMzZnN04AoBDBkQKEGmACiwzBxqANAuESxbsEsAfQSmb0Wpku5mJGzEfqe3kiQAhgDIXmCiE6xD1wCuXKEHiAlkjso8QffvCSBZlEA0wqAPoItReQ7Y1m+MkWbGPvHiz1MI7TAsjF5iqzIAkeDEQP3PGoBve93PFrMGI7KlJwLyJ8XgK1aLw1pDvYgVmS1FbSMhdKc2AAI+50AjqyNGvoUSPFc0GxifB6veMtSoyXytAHEKnL0bVMDpyI2gMdPXRnSYpF0xPjAgZrjk2oHUXyHsgCjsNCosnGDDBEiibYqoUzeqMlBUBqBmoGUauVlFhhvEAA+nqEQBDz6JesOgEPPEpgxWo7UAeQeQOACABgBwAYJgR6IABWAABxbyFBseLeWgC3l0Ac0AwAYAwAABsW8voGgD6BHyo8G8tAAoIUFbzY8c8gwAPKfk5pz5xJPoLQA3mygt5l82gAAHZY8p8hgLQEwIHzl5CglQBvPPmx4o8f8zArQCjzGFMoPke2RvIYBgKSAZ84kvAr6AkAFBBwc+bArPm0AcFseCBVvIODAKt5lCqPMAoUF9AN5UCt+e/MwVlR1AI8jNOPNeaTzaAQ8vyHPKAA=== -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=GoTogether-Inc/frontend&utm_content=211):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (7)
tailwind.config.js (1)

70-71: 색상 네이밍 충돌 여부 확인

myPageBg 컬러가 추가됐습니다. 다른 곳에서 동일한 키로 이미 확장한 적이 없다면 문제 없으나, 전역 테마 충돌 위험이 있으니 확인 바랍니다.

src/entities/user/ui/EventInfo.tsx (1)

10-10: cursor-pointer 조건부 적용 고려

onClick이 전달되지 않아도 커서가 포인터로 표시됩니다. UX 혼란을 방지하려면 onClick 존재 여부에 따라 포인터 적용을 분기하세요.

design-system/ui/buttons/TertiaryButton.tsx (1)

5-5: 전체 너비 버튼 구현 승인

새로운 'full' 사이즈 옵션이 적절히 구현되었습니다. w-full 클래스로 전체 너비를 제공하고 적절한 패딩과 텍스트 크기를 설정했습니다.

패딩 일관성 고려사항

full 사이즈의 py-1 패딩이 다른 사이즈들과 비교해서 적절한지 확인해보세요. medium 사이즈도 py-1을 사용하는데, 전체 너비 버튼에는 조금 더 큰 패딩이 적합할 수 있습니다.

Also applies to: 19-19

src/entities/user/ui/BookmarkList.tsx (1)

7-13: 데이터 처리 로직 개선 제안

현재 구현은 잘 작동하지만, 다음과 같은 개선사항을 고려해보세요:

  1. 로딩 및 에러 상태 처리: useBookmarks 훅에서 isLoading, error 상태를 구조 분해하여 사용자 경험을 개선할 수 있습니다.
  2. 메모이제이션: 정렬 로직을 useMemo로 메모이제이션하여 성능을 최적화할 수 있습니다.
-  const { data } = useBookmarks();
+  const { data, isLoading, error } = useBookmarks();
   const navigate = useNavigate();
 
-  const sortedData = data ? [...data].sort((a, b) => a.id - b.id) : [];
-  const visibleEvents = sortedData.slice(0, 2);
+  const visibleEvents = useMemo(() => {
+    if (!data) return [];
+    return [...data].sort((a, b) => a.id - b.id).slice(0, 2);
+  }, [data]);
src/pages/menu/ui/MyPage.tsx (3)

54-63: 이메일 링크 구현이 잘 되었습니다만, 개선사항이 있습니다.

이메일 링크에 미리 설정된 제목과 내용이 포함되어 있어 사용자 경험이 좋습니다. 다만 몇 가지 개선사항을 제안드립니다:

  1. 이메일 주소가 하드코딩되어 있습니다
  2. 긴 이메일 내용으로 인해 URL이 매우 길어질 수 있습니다
+// 상수로 분리
+const CONTACT_EMAIL = 'gotogether@gmail.com';
+const EMAIL_SUBJECT = '같이가요 서비스 문의';
+const EMAIL_BODY = `안녕하세요, 같이가요 서비스 개발팀입니다.

서비스 이용 중 발생한 오류나 불편 사항을 공유해주시면, 더 나은 서비스 제공에 큰 도움이 됩니다.
정확한 확인을 위해 [화면 캡처, 페이지 위치, 에러 내용] 등을 함께 작성해주시면 감사하겠습니다.`;

                <a
-                  href={`mailto:gotogether@gmail.com?subject=${encodeURIComponent(
-                    '같이가요 서비스 문의'
-                  )}&body=${encodeURIComponent(`안녕하세요, 같이가요 서비스 개발팀입니다.
-
-서비스 이용 중 발생한 오류나 불편 사항을 공유해주시면, 더 나은 서비스 제공에 큰 도움이 됩니다.
-정확한 확인을 위해 [화면 캡처, 페이지 위치, 에러 내용] 등을 함께 작성해주시면 감사하겠습니다.`)}`}
+                  href={`mailto:${CONTACT_EMAIL}?subject=${encodeURIComponent(EMAIL_SUBJECT)}&body=${encodeURIComponent(EMAIL_BODY)}`}
                  className="text-sm md:text-medium font-semibold underline text-blue-600"
                >
-                  gotogether@gmail.com
+                  {CONTACT_EMAIL}
                </a>

26-32: 중복된 onClick 핸들러를 제거하세요.

티켓 정보 섹션에서 div와 IconButton 모두에 동일한 onClick 핸들러가 설정되어 있습니다. 이는 중복 호출을 발생시킬 수 있습니다.

          <div onClick={() => navigate('/menu/myTicket')} className="flex items-center justify-between cursor-pointer">
            <span className="text-medium md:text-lg font-semibold">구매한 티켓 정보</span>
            <IconButton
              iconPath={<img src={arrow} alt="화살표" className="w-2" />}
-              onClick={() => navigate('/menu/myTicket')}
            />
          </div>

69-72: 로그아웃 섹션도 동일한 중복 문제가 있습니다.

티켓 정보 섹션과 마찬가지로 중복된 onClick 핸들러가 있습니다.

          <div onClick={handleLogout} className="flex items-center justify-between cursor-pointer">
            <span className="text-medium md:text-lg text-red-500 font-semibold">로그아웃</span>
-            <IconButton iconPath={<img src={logout} alt="로그아웃" className="w-4" />} onClick={handleLogout} />
+            <IconButton iconPath={<img src={logout} alt="로그아웃" className="w-4" />} />
          </div>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 328e896 and eacfb1f.

⛔ Files ignored due to path filters (4)
  • public/assets/bottomBar/Arrow.svg is excluded by !**/*.svg
  • public/assets/bottomBar/Bookmark.svg is excluded by !**/*.svg
  • public/assets/bottomBar/Logout.svg is excluded by !**/*.svg
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (13)
  • design-system/stories/buttons/TertiaryButton.stories.tsx (2 hunks)
  • design-system/ui/buttons/TertiaryButton.tsx (2 hunks)
  • design-system/ui/textFields/DefaultTextField.tsx (3 hunks)
  • package.json (3 hunks)
  • src/app/Layout.tsx (1 hunks)
  • src/entities/user/ui/BookmarkList.tsx (1 hunks)
  • src/entities/user/ui/EventInfo.tsx (1 hunks)
  • src/entities/user/ui/ProfileInfo.tsx (1 hunks)
  • src/features/event/ui/ShareEventModal.tsx (2 hunks)
  • src/pages/event/ui/EventDetailsPage.tsx (1 hunks)
  • src/pages/menu/ui/MyPage.tsx (1 hunks)
  • src/shared/ui/FloatingButton.tsx (2 hunks)
  • tailwind.config.js (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/entities/user/ui/BookmarkList.tsx (2)
src/features/bookmark/hook/useBookmarkHook.ts (1)
  • useBookmarks (6-11)
src/shared/lib/date.ts (1)
  • formatDate (1-9)
🔇 Additional comments (9)
src/shared/ui/FloatingButton.tsx (1)

19-20: right-100 Tailwind 유틸리티가 실제로 동작하는지 확인 필요

Tailwind 기본 spacing scale에는 100 값이 없으며, extend.spacing에도 100이 정의돼 있지 않습니다.
정의가 없다면 right-100 클래스는 빌드 시 CSS가 생성되지 않아 절대 위치가 적용되지 않습니다.
right-24 (6rem) 같이 존재하는 spacing 값으로 교체하거나, 임의 픽셀 값을 사용할 경우 right-[100px] 형태로 지정하세요.

src/app/Layout.tsx (1)

4-4: UI 개선 반영 확인

테두리(border border-gray-200) 추가로 콘텐츠 영역 구분이 명확해졌습니다. 의도한 디자인 변화라면 문제 없습니다.

package.json (1)

23-23: 새로운 종속성 추가 승인

추가된 종속성들은 UI 개선과 컴포넌트 기능 향상에 적합한 선택입니다:

  • classnames: 조건부 CSS 클래스 관리에 널리 사용되는 라이브러리
  • react-virtuoso: 북마크 목록 같은 큰 리스트의 효율적인 렌더링 지원
  • @types/classnames: TypeScript 타입 안전성 제공

버전들도 안정적이고 최신 상태입니다.

Also applies to: 38-38, 58-58

src/features/event/ui/ShareEventModal.tsx (1)

5-5: 컴포넌트 재사용성 향상

EventInfo 컴포넌트를 도입하여 이벤트 정보 표시를 일관성 있게 개선했습니다. 이는 UI 컴포넌트의 재사용성을 높이고 전체 애플리케이션의 일관성을 보장하는 좋은 리팩토링입니다.

Also applies to: 75-75

design-system/stories/buttons/TertiaryButton.stories.tsx (1)

34-34: 디자인 시스템 확장 승인

새로운 "full" 사이즈 옵션과 해당 스토리가 적절히 추가되었습니다. 전체 너비 버튼 옵션은 마이페이지 같은 폼 인터페이스에서 유용할 것입니다.

Also applies to: 92-99

src/entities/user/ui/BookmarkList.tsx (2)

21-33: 접근성과 사용자 경험 향상

렌더링 로직이 잘 구현되었습니다. 빈 상태 메시지도 적절하고, 접근성을 고려한 alt 텍스트도 훌륭합니다.


34-39: 네비게이션 링크 구현 우수

"전체 관심 이벤트 보기" 링크가 적절히 구현되었습니다. 스타일링과 인터랙션이 잘 처리되어 있습니다.

design-system/ui/textFields/DefaultTextField.tsx (2)

17-17: 타입 정의가 완벽합니다.

errorPosition 속성에 대한 타입 정의가 명확하고 적절합니다. 기본값 설정도 잘 되어 있습니다.


71-81: 에러 메시지 반복 렌더링 문제가 있습니다.

errorPosition이 'right'일 때 모바일에서는 두 번의 에러 메시지가 렌더링될 수 있습니다 (78번째 줄과 86번째 줄).

            {errorMessage && errorPosition === 'right' && (
              <>
                {/* 데스크탑일 때만 오른쪽에 보이기 */}
                <p className="hidden md:block absolute left-full top-1/2 -translate-y-1/2 ml-2 text-xs text-red-500 whitespace-nowrap">
                  {errorMessage}
                </p>
-                {/* 모바일에서는 아래에 표시 */}
-                <p className="md:hidden mt-1 text-xs text-red-500">{errorMessage}</p>
              </>
            )}

그리고 86번째 줄도 수정해주세요:

-        {errorMessage && errorPosition !== 'right' && <p className="mt-1 text-xs text-red-500">{errorMessage}</p>}
+        {errorMessage && errorPosition !== 'right' && (
+          <p className="mt-1 text-xs text-red-500">{errorMessage}</p>
+        )}
+        {errorMessage && errorPosition === 'right' && (
+          <p className="md:hidden mt-1 text-xs text-red-500">{errorMessage}</p>
+        )}

Likely an incorrect or invalid review comment.

Comment on lines +40 to 47
<img
src={arrow}
alt="화살표"
className={`w-2 transition-transform duration-300 ${open ? 'rotate-90' : ''}`}
/>
}
onClick={handleToggle}
/>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

접근성 개선을 위해 키보드 네비게이션을 지원하세요.

현재 토글 기능이 클릭에만 반응합니다. 키보드 사용자를 위한 접근성을 개선해주세요.

-            <div onClick={handleToggle} className="flex items-center justify-between cursor-pointer">
+            <div 
+              onClick={handleToggle} 
+              onKeyDown={(e) => {
+                if (e.key === 'Enter' || e.key === ' ') {
+                  e.preventDefault();
+                  handleToggle();
+                }
+              }}
+              tabIndex={0}
+              role="button"
+              aria-expanded={open}
+              aria-controls="inquiry-content"
+              className="flex items-center justify-between cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:rounded"
+            >

그리고 콘텐츠 영역에도 적절한 id를 추가해주세요:

-            {open && (
-              <div className="mt-3">
+            {open && (
+              <div id="inquiry-content" className="mt-3">

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/pages/menu/ui/MyPage.tsx around lines 40 to 47, the toggle element only
responds to mouse clicks, lacking keyboard accessibility. To fix this, add
keyboard event handlers such as onKeyDown to support toggling via keyboard keys
like Enter or Space. Also, ensure the toggle element is focusable by adding
tabIndex if necessary. Additionally, assign a proper id attribute to the content
area associated with the toggle for better accessibility and ARIA support.

Comment on lines +61 to +73
if (isLoading) {
return <div>로딩 중...</div>;
}
if (error) {
return <div>정보를 불러오는데 실패했습니다. 다시 시도해주세요.</div>;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

로딩 및 에러 상태 UI가 너무 단순합니다.

현재 로딩과 에러 상태가 단순한 텍스트로만 표시되어 있어 사용자 경험이 좋지 않습니다. 디자인 시스템의 컴포넌트를 활용하여 개선해주세요.

  if (isLoading) {
-    return <div>로딩 중...</div>;
+    return (
+      <div className="relative w-full h-52 md:h-56">
+        <div className="absolute inset-0 bg-main rounded-[10px]" />
+        <div className="relative z-10 bg-dashboardBg rounded-[10px] p-5 ml-2 h-full flex items-center justify-center">
+          <div className="text-center">
+            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-main mx-auto mb-2"></div>
+            <p className="text-sm text-gray-600">프로필 정보를 불러오는 중...</p>
+          </div>
+        </div>
+      </div>
+    );
  }
  if (error) {
-    return <div>정보를 불러오는데 실패했습니다. 다시 시도해주세요.</div>;
+    return (
+      <div className="relative w-full h-52 md:h-56">
+        <div className="absolute inset-0 bg-main rounded-[10px]" />
+        <div className="relative z-10 bg-dashboardBg rounded-[10px] p-5 ml-2 h-full flex items-center justify-center">
+          <div className="text-center">
+            <p className="text-sm text-red-500 mb-2">프로필 정보를 불러오는데 실패했습니다.</p>
+            <TertiaryButton
+              label="다시 시도"
+              type="button"
+              color="pink"
+              size="small"
+              onClick={() => refetch()}
+            />
+          </div>
+        </div>
+      </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
if (isLoading) {
return <div>로딩 중...</div>;
}
if (error) {
return <div>정보를 불러오는데 실패했습니다. 다시 시도해주세요.</div>;
}
if (isLoading) {
return (
<div className="relative w-full h-52 md:h-56">
<div className="absolute inset-0 bg-main rounded-[10px]" />
<div className="relative z-10 bg-dashboardBg rounded-[10px] p-5 ml-2 h-full flex items-center justify-center">
<div className="text-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-main mx-auto mb-2"></div>
<p className="text-sm text-gray-600">프로필 정보를 불러오는 중...</p>
</div>
</div>
</div>
);
}
if (error) {
return (
<div className="relative w-full h-52 md:h-56">
<div className="absolute inset-0 bg-main rounded-[10px]" />
<div className="relative z-10 bg-dashboardBg rounded-[10px] p-5 ml-2 h-full flex items-center justify-center">
<div className="text-center">
<p className="text-sm text-red-500 mb-2">프로필 정보를 불러오는데 실패했습니다.</p>
<TertiaryButton
label="다시 시도"
type="button"
color="pink"
size="small"
onClick={() => refetch()}
/>
</div>
</div>
</div>
);
}
🤖 Prompt for AI Agents
In src/entities/user/ui/ProfileInfo.tsx around lines 61 to 66, the loading and
error UI states are currently rendered as simple text, which results in poor
user experience. Replace these plain div elements with appropriate components
from the design system, such as a spinner or loader component for the loading
state and a styled alert or error message component for the error state, to
enhance visual feedback and consistency.

Comment on lines +74 to +78
<p className="hidden md:block absolute left-full top-1/2 -translate-y-1/2 ml-2 text-xs text-red-500 whitespace-nowrap">
{errorMessage}
</p>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

오른쪽 에러 메시지 위치 조정이 필요합니다.

현재 left-fullml-2 조합은 에러 메시지가 입력 필드를 벗어나 화면 밖으로 나갈 수 있습니다.

-                <p className="hidden md:block absolute left-full top-1/2 -translate-y-1/2 ml-2 text-xs text-red-500 whitespace-nowrap">
+                <p className="hidden md:block absolute left-full top-1/2 -translate-y-1/2 ml-2 text-xs text-red-500 whitespace-nowrap z-10 bg-white px-1 rounded shadow-sm">
                  {errorMessage}
                </p>

또한 컨테이너에 오버플로우 처리를 추가해주세요:

-          <div className="relative w-full">
+          <div className="relative w-full overflow-visible">
📝 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
<p className="hidden md:block absolute left-full top-1/2 -translate-y-1/2 ml-2 text-xs text-red-500 whitespace-nowrap">
{errorMessage}
</p>
<div className="relative w-full overflow-visible">
{/* ...your input markup... */}
{errorMessage && (
<p className="hidden md:block absolute left-full top-1/2 -translate-y-1/2 ml-2 text-xs text-red-500 whitespace-nowrap z-10 bg-white px-1 rounded shadow-sm">
{errorMessage}
</p>
)}
</div>
🤖 Prompt for AI Agents
In design-system/ui/textFields/DefaultTextField.tsx around lines 74 to 76, the
error message positioning uses 'left-full' and 'ml-2', which can cause the
message to overflow outside the viewport. Adjust the positioning to keep the
error message visible within the container, for example by using relative
positioning or adjusting left/right values. Additionally, add overflow handling
(like 'overflow-auto' or 'overflow-hidden') to the container element to prevent
content from spilling out visually.

Copy link
Member

@hyeeuncho hyeeuncho left a comment

Choose a reason for hiding this comment

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

수고하셨습니다

@Yejiin21 Yejiin21 force-pushed the design/#205/publishing-mypage branch from 99ef6ba to 25c41e1 Compare July 4, 2025 03:32
@github-actions
Copy link

github-actions bot commented Jul 4, 2025

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/pages/menu/ui/MyPage.tsx (1)

36-48: 키보드 접근성 개선이 여전히 필요합니다.

과거 리뷰에서 지적된 키보드 접근성 문제가 여전히 존재합니다. 키보드 사용자를 위한 접근성을 개선해주세요.

-            <div onClick={handleToggle} className="flex items-center justify-between cursor-pointer">
+            <div 
+              onClick={handleToggle} 
+              onKeyDown={(e) => {
+                if (e.key === 'Enter' || e.key === ' ') {
+                  e.preventDefault();
+                  handleToggle();
+                }
+              }}
+              tabIndex={0}
+              role="button"
+              aria-expanded={open}
+              aria-controls="inquiry-content"
+              className="flex items-center justify-between cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:rounded"
+            >

그리고 콘텐츠 영역에도 적절한 id를 추가해주세요:

-            {open && (
-              <div className="mt-3">
+            {open && (
+              <div id="inquiry-content" className="mt-3">
🧹 Nitpick comments (3)
src/pages/menu/ui/MyPage.tsx (3)

53-63: 이메일 본문을 상수로 분리하여 가독성을 개선하세요.

인라인으로 작성된 긴 이메일 본문이 코드 가독성을 해칩니다.

컴포넌트 상단에 상수를 정의하여 개선할 수 있습니다:

+const EMAIL_TEMPLATE = {
+  subject: '같이가요 서비스 문의',
+  body: `안녕하세요, 같이가요 서비스 개발팀입니다.
+
+서비스 이용 중 발생한 오류나 불편 사항을 공유해주시면, 더 나은 서비스 제공에 큰 도움이 됩니다.
+정확한 확인을 위해 [화면 캡처, 페이지 위치, 에러 내용] 등을 함께 작성해주시면 감사하겠습니다.`
+};
+
 const MyPage = () => {
   // ...
   
-                <a
-                  href={`mailto:gotogether@gmail.com?subject=${encodeURIComponent(
-                    '같이가요 서비스 문의'
-                  )}&body=${encodeURIComponent(`안녕하세요, 같이가요 서비스 개발팀입니다.
-
-서비스 이용 중 발생한 오류나 불편 사항을 공유해주시면, 더 나은 서비스 제공에 큰 도움이 됩니다.
-정확한 확인을 위해 [화면 캡처, 페이지 위치, 에러 내용] 등을 함께 작성해주시면 감사하겠습니다.`)}`}
+                <a
+                  href={`mailto:gotogether@gmail.com?subject=${encodeURIComponent(
+                    EMAIL_TEMPLATE.subject
+                  )}&body=${encodeURIComponent(EMAIL_TEMPLATE.body)}`}

26-31: 중복된 이벤트 핸들러를 정리하세요.

div와 IconButton 모두에 동일한 onClick 핸들러가 있어 중복 호출될 수 있습니다.

IconButton에서 onClick을 제거하거나 div에서 onClick을 제거하세요:

-          <div onClick={() => navigate('/menu/myTicket')} className="flex items-center justify-between cursor-pointer">
+          <div className="flex items-center justify-between cursor-pointer">
             <span className="text-medium md:text-lg font-semibold">구매한 티켓 정보</span>
             <IconButton
               iconPath={<img src={arrow} alt="화살표" className="w-2" />}
               onClick={() => navigate('/menu/myTicket')}
             />

또는 전체 div에만 핸들러를 유지하고 IconButton에서 제거:

           <div onClick={() => navigate('/menu/myTicket')} className="flex items-center justify-between cursor-pointer">
             <span className="text-medium md:text-lg font-semibold">구매한 티켓 정보</span>
             <IconButton
               iconPath={<img src={arrow} alt="화살표" className="w-2" />}
-              onClick={() => navigate('/menu/myTicket')}
             />

69-72: 로그아웃 섹션에서도 중복된 이벤트 핸들러를 정리하세요.

여기서도 동일한 중복 이벤트 핸들러 문제가 있습니다.

-          <div onClick={handleLogout} className="flex items-center justify-between cursor-pointer">
+          <div className="flex items-center justify-between cursor-pointer">
             <span className="text-medium md:text-lg text-red-500 font-semibold">로그아웃</span>
             <IconButton iconPath={<img src={logout} alt="로그아웃" className="w-4" />} onClick={handleLogout} />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99ef6ba and 25c41e1.

⛔ Files ignored due to path filters (4)
  • public/assets/bottomBar/Arrow.svg is excluded by !**/*.svg
  • public/assets/bottomBar/Bookmark.svg is excluded by !**/*.svg
  • public/assets/bottomBar/Logout.svg is excluded by !**/*.svg
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (17)
  • design-system/stories/buttons/TertiaryButton.stories.tsx (2 hunks)
  • design-system/ui/buttons/TertiaryButton.tsx (2 hunks)
  • design-system/ui/textFields/DefaultTextField.tsx (3 hunks)
  • package.json (1 hunks)
  • src/app/Layout.tsx (1 hunks)
  • src/entities/user/ui/BookmarkList.tsx (1 hunks)
  • src/entities/user/ui/EventInfo.tsx (1 hunks)
  • src/entities/user/ui/ProfileInfo.tsx (1 hunks)
  • src/features/event/ui/ShareEventModal.tsx (2 hunks)
  • src/pages/event/ui/AllEventsPage.tsx (2 hunks)
  • src/pages/event/ui/CategoryPage.tsx (2 hunks)
  • src/pages/event/ui/EventDetailsPage.tsx (1 hunks)
  • src/pages/home/ui/MainPage.tsx (4 hunks)
  • src/pages/menu/ui/MyPage.tsx (1 hunks)
  • src/shared/lib/formatProfileName.ts (1 hunks)
  • src/shared/ui/FloatingButton.tsx (2 hunks)
  • tailwind.config.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (16)
  • package.json
  • src/app/Layout.tsx
  • src/shared/lib/formatProfileName.ts
  • src/shared/ui/FloatingButton.tsx
  • tailwind.config.js
  • src/pages/event/ui/CategoryPage.tsx
  • src/pages/event/ui/EventDetailsPage.tsx
  • src/pages/event/ui/AllEventsPage.tsx
  • src/pages/home/ui/MainPage.tsx
  • design-system/stories/buttons/TertiaryButton.stories.tsx
  • src/entities/user/ui/BookmarkList.tsx
  • design-system/ui/buttons/TertiaryButton.tsx
  • src/entities/user/ui/EventInfo.tsx
  • src/features/event/ui/ShareEventModal.tsx
  • src/entities/user/ui/ProfileInfo.tsx
  • design-system/ui/textFields/DefaultTextField.tsx
🔇 Additional comments (3)
src/pages/menu/ui/MyPage.tsx (3)

1-9: 컴포넌트 import 구조가 개선되었습니다.

리팩토링으로 인해 import 구조가 깔끔해졌고, 필요한 의존성들이 명확하게 분리되었습니다.


12-16: 상태 관리 로직이 적절합니다.

toggle 상태와 네비게이션 핸들러가 깔끔하게 구현되었습니다.


19-23: 컴포넌트 분리를 통한 깔끔한 구조.

ProfileInfo와 BookmarkList 컴포넌트로 분리하여 코드 가독성과 유지보수성이 크게 향상되었습니다.

@Yejiin21 Yejiin21 merged commit 838638a into develop Jul 4, 2025
2 checks passed
@Yejiin21 Yejiin21 deleted the design/#205/publishing-mypage branch July 4, 2025 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔧 Feature 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[design] 마이페이지 퍼블리싱

3 participants