Repository: WillYouMerryMe/getting-married
Pull request #46: feat(mobile): 마이 페이지 퍼블리싱
Author: login: junghongseop
Created: 2025-05-08T06:58:17Z | Merged: 2025-05-08T07:18:03Z

## 📄 Summary

> 마이 페이지를 퍼블리싱 했습니다.

<br>

## 🔨 Tasks

- 브랜드 뱃지 컴포넌트 개발
- 마이 페이지 퍼블리싱
- 헤드셋과 확성기 아이콘 컴포넌트 개발

<br>

## 🙋🏻 More
<img width="379" alt="스크린샷 2025-05-08 오후 3 51 34" src="https://github.com/user-attachments/assets/0e348001-d66c-401c-83f6-1676dadd25ed" />


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **신규 기능**
    - 마이페이지 화면의 UI가 개선되어 사용자 정보, 브랜드 배지, 고객지원 및 공지사항 리스트가 추가되었습니다.
    - 새로운 아이콘(헤드셋, 메가폰)이 지원됩니다.
    - 브랜드 구분 배지 컴포넌트가 도입되어, 카카오/네이버 계정임을 시각적으로 표시합니다.

- **스타일**
    - 마이페이지 레이아웃과 구성 요소들의 배경색, 정렬, 패딩 등 디자인이 개선되었습니다.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/apps/mobile/src/app/my/page.tsx b/apps/mobile/src/app/my/page.tsx
index e4588aae..3d40797f 100644
--- a/apps/mobile/src/app/my/page.tsx
+++ b/apps/mobile/src/app/my/page.tsx
@@ -1,14 +1,34 @@
 'use client';
 
+import MyInfoList from '@/components/my/MyInfoList/MyInfoList';
 import AppLayout from '@/layouts/AppLayout';
 import { color } from '@merried/design-system';
+import { Text } from '@merried/ui';
+import { flex } from '@merried/utils';
+import styled from 'styled-components';
 
 const My = () => {
   return (
-    <AppLayout footer backgroundColor={color.G20}>
-      마이페이지
+    <AppLayout footer backgroundColor={color.G0}>
+      <StyledMy>
+        <Text fontType="H2" color={color.G900}>
+          마이페이지
+        </Text>
+        <MyInfoList />
+      </StyledMy>
     </AppLayout>
   );
 };
 
 export default My;
+
+const StyledMy = styled.div`
+  ${flex({
+    flexDirection: 'column',
+    alignItems: 'flex-start',
+    justifyContent: 'flex-start',
+  })}
+  width: 100%;
+  gap: 36px;
+  padding: 71px 18px 115px;
+`;
diff --git a/apps/mobile/src/components/my/ListItem/ListItem.tsx b/apps/mobile/src/components/my/ListItem/ListItem.tsx
new file mode 100644
index 00000000..66774efb
--- /dev/null
+++ b/apps/mobile/src/components/my/ListItem/ListItem.tsx
@@ -0,0 +1,41 @@
+import { color } from '@merried/design-system';
+import { IconArrow } from '@merried/icon';
+import { Row, Text } from '@merried/ui';
+import { flex } from '@merried/utils';
+import { SVGProps } from 'react';
+import styled from 'styled-components';
+
+interface ListItemProps {
+  icon: React.ComponentType<SVGProps<SVGSVGElement>>;
+  title: string;
+}
+
+const ListItem = ({ icon: Icon, title }: ListItemProps) => {
+  const handleItemClick = () => {
+    alert('추후 개발 예정입니다.');
+  };
+
+  return (
+    <StyledListItem onClick={handleItemClick}>
+      <Row gap={8} alignItems="center">
+        <Icon width={22} height={22} />
+        <Text fontType="P3" color={color.G300}>
+          {title}
+        </Text>
+      </Row>
+      <IconArrow width={18} height={18} direction="left" />
+    </StyledListItem>
+  );
+};
+
+export default ListItem;
+
+const StyledListItem = styled.div`
+  ${flex({
+    flexDirection: 'row',
+    alignItems: 'center',
+    justifyContent: 'space-between',
+  })}
+  width: 100%;
+  padding: 8px 0px;
+`;
diff --git a/apps/mobile/src/components/my/MyInfo/MyInfo.tsx b/apps/mobile/src/components/my/MyInfo/MyInfo.tsx
new file mode 100644
index 00000000..2dd272fb
--- /dev/null
+++ b/apps/mobile/src/components/my/MyInfo/MyInfo.tsx
@@ -0,0 +1,35 @@
+import { color } from '@merried/design-system';
+import { BrandBadge, Column, Row, Text } from '@merried/ui';
+import { flex } from '@merried/utils';
+import styled from 'styled-components';
+
+const MyInfo = () => {
+  return (
+    <StyledMyInfo onClick={() => {}}>
+      <Column gap={4}>
+        <Row gap={8} alignItems="center">
+          <Text fontType="H3" color={color.G900}>
+            박강원님
+          </Text>
+          <BrandBadge type="NAVER" />
+        </Row>
+        <Text fontType="P3" color={color.G60}>
+          pkw0227@gmail.com
+        </Text>
+      </Column>
+      <div onClick={() => {}}>
+        <Text fontType="P3" color={color.G100}>
+          로그아웃
+        </Text>
+      </div>
+    </StyledMyInfo>
+  );
+};
+
+export default MyInfo;
+
+const StyledMyInfo = styled.div`
+  ${flex({ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' })}
+  width: 100%;
+  height: 51px;
+`;
diff --git a/apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx b/apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx
new file mode 100644
index 00000000..3b6578e0
--- /dev/null
+++ b/apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx
@@ -0,0 +1,36 @@
+import { color } from '@merried/design-system';
+import styled from 'styled-components';
+import MyInfo from '../MyInfo/MyInfo';
+import ListItem from '../ListItem/ListItem';
+import { IconHeadset, IconMegaphone } from '@merried/icon';
+import { Column } from '@merried/ui';
+import { flex } from '@merried/utils';
+
+const MyInfoList = () => {
+  return (
+    <StyledMyInfoList>
+      <MyInfo />
+      <Spacer />
+      <Column gap={4}>
+        <ListItem icon={IconHeadset} title="고객지원" />
+        <ListItem icon={IconMegaphone} title="공지사항" />
+      </Column>
+    </StyledMyInfoList>
+  );
+};
+
+export default MyInfoList;
+
+const StyledMyInfoList = styled.div`
+  ${flex({ flexDirection: 'column', alignItems: 'flex-start' })}
+  width: 100%;
+  gap: 16px;
+`;
+
+const Spacer = styled.div`
+  width: calc(100% + 36px);
+  height: 10px;
+  background-color: ${color.G10};
+  position: relative;
+  left: -18px;
+`;
diff --git a/packages/icon/index.ts b/packages/icon/index.ts
index 5efa2774..24b4954c 100644
--- a/packages/icon/index.ts
+++ b/packages/icon/index.ts
@@ -15,4 +15,6 @@ export { default as IconCircleAdd } from './src/IconCircleAdd';
 export { default as IconDelete } from './src/IconDelete';
 export { default as IconSearch } from './src/IconSearch';
 export { default as IconPencil } from './src/IconPencil';
+export { default as IconHeadset } from './src/IconHeadset';
+export { default as IconMegaphone } from './src/IconMegaphone';
 export { default as IconDragHandle } from './src/IconDragHandle';
diff --git a/packages/icon/src/IconHeadset.tsx b/packages/icon/src/IconHeadset.tsx
new file mode 100644
index 00000000..ed9f0340
--- /dev/null
+++ b/packages/icon/src/IconHeadset.tsx
@@ -0,0 +1,32 @@
+import type { SVGProps } from 'react';
+import React from 'react';
+
+const IconHeadset = (props: SVGProps<SVGSVGElement>) => (
+  <svg viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
+    <g clipPath="url(#clip0_183_1378)">
+      <path
+        d="M17.4163 8.25C17.4163 5.21243 14.5435 2.75 10.9997 2.75C7.45585 2.75 4.58301 5.21243 4.58301 8.25"
+        stroke="#686868"
+        strokeWidth="2"
+      />
+      <path
+        d="M17.1113 7.33301V7.33301C18.7989 7.33301 20.1669 8.70103 20.1669 10.3886V11.1525C20.1669 12.84 18.7989 14.208 17.1113 14.208V14.208V7.33301Z"
+        stroke="#686868"
+        strokeWidth="2"
+      />
+      <path
+        d="M4.88867 7.33301V7.33301C3.20113 7.33301 1.83312 8.70103 1.83312 10.3886V11.1525C1.83312 12.84 3.20113 14.208 4.88867 14.208V14.208V7.33301Z"
+        stroke="#686868"
+        strokeWidth="2"
+      />
+      <path d="M10.2363 18.7913H12.528L17.1113 14.208" stroke="#686868" strokeWidth="2" />
+    </g>
+    <defs>
+      <clipPath id="clip0_183_1378">
+        <rect width="22" height="22" fill="white" />
+      </clipPath>
+    </defs>
+  </svg>
+);
+
+export default IconHeadset;
diff --git a/packages/icon/src/IconMegaphone.tsx b/packages/icon/src/IconMegaphone.tsx
new file mode 100644
index 00000000..e7bff669
--- /dev/null
+++ b/packages/icon/src/IconMegaphone.tsx
@@ -0,0 +1,14 @@
+import type { SVGProps } from 'react';
+import React from 'react';
+
+const IconMegaphone = (props: SVGProps<SVGSVGElement>) => (
+  <svg viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
+    <path
+      d="M7.7824 7.07598C11.0308 6.18131 18.0616 4 18.0616 4V17.6223C18.0616 17.6223 11.4702 14.9857 7.7824 13.4611M7.7824 7.07598C4 7.07639 6.19713 7.07598 4 7.07598V12.7046L4.75648 13.4611V18H7.7824V13.4611M7.7824 7.07598V13.4611"
+      stroke="#686868"
+      strokeWidth="1.51296"
+    />
+  </svg>
+);
+
+export default IconMegaphone;
diff --git a/packages/ui/index.ts b/packages/ui/index.ts
index b02decb9..75895119 100644
--- a/packages/ui/index.ts
+++ b/packages/ui/index.ts
@@ -10,3 +10,4 @@ export { default as Column } from './src/Flex/Column';
 export { default as Text } from './src/Text/Text';
 export { default as LoginButton } from './src/Button/LoginButton';
 export { default as InsertPhoto } from './src/InsertPhoto/InsertPhoto';
+export { default as BrandBadge} from './src/BrandBadge/BrandBadge'
\ No newline at end of file
diff --git a/packages/ui/src/BrandBadge/BrandBadge.tsx b/packages/ui/src/BrandBadge/BrandBadge.tsx
new file mode 100644
index 00000000..dd2d24c2
--- /dev/null
+++ b/packages/ui/src/BrandBadge/BrandBadge.tsx
@@ -0,0 +1,31 @@
+import { color } from '@merried/design-system';
+import { flex } from '@merried/utils';
+import styled from 'styled-components';
+import Text from '../Text/Text';
+
+interface BrandBadgeProps {
+  type: 'KAKAO' | 'NAVER';
+}
+
+const BrandBadge = ({ type }: BrandBadgeProps) => {
+  return (
+    <StyledBrandBadge $badgeType={type}>
+      <Text fontType="P4" color={type === 'NAVER' ? color.G0 : color.G400}>
+        {type === 'NAVER' ? '네이버' : '카카오'}
+      </Text>
+    </StyledBrandBadge>
+  );
+};
+
+export default BrandBadge;
+
+const StyledBrandBadge = styled.div<{ $badgeType: BrandBadgeProps['type'] }>`
+  ${flex({ alignItems: 'center', justifyContent: 'center' })}
+  width: 60px;
+  height: 28px;
+  background: ${({ $badgeType }) =>
+    $badgeType === 'NAVER' ? 'rgba(4, 199, 91, 0.6)' : 'rgba(250, 225, 0, 0.6)'};
+  border-radius: 999px;
+  border: 1px solid
+    ${({ $badgeType }) => ($badgeType === 'NAVER' ? '#04C75B' : '#fae100')};
+`;


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 5**

<details>
<summary>🧹 Nitpick comments (5)</summary><blockquote>

<details>
<summary>packages/icon/src/IconHeadset.tsx (1)</summary><blockquote>

`1-32`: **헤드셋 아이콘이 멋지게 구현되었어요! 👏**

이 헤드셋 아이콘도 확성기 아이콘처럼 잘 만들어졌네요! SVG의 여러 경로(path)들을 사용해서 더 복잡한 형태를 표현했어요.

작은 부분들을 개선할 수 있는 방법이 있어요:

1. clipPath의 ID가 "clip0_183_1378"로 되어 있는데, 이런 ID는 디자인 도구에서 자동 생성된 것 같아요. 만약 같은 ID를 가진 다른 요소가 페이지에 있다면 문제가 생길 수 있어요. 좀 더 의미 있는 이름으로 바꿔주면 좋을 것 같아요.

2. 또한, 확성기 아이콘은 strokeWidth가 1.51296인데, 이 아이콘은 2로 설정되어 있어요. 일관성을 위해 같은 값을 사용하는 것을 고려해보세요.

```diff
-    <g clipPath="url(#clip0_183_1378)">
+    <g clipPath="url(#clip-headset-icon)">

...

-      <clipPath id="clip0_183_1378">
+      <clipPath id="clip-headset-icon">
```

위의 변경 사항들은 선택 사항이니, 꼭 수정하지 않아도 돼요! 현재 코드도 잘 작동할 거예요.

</blockquote></details>
<details>
<summary>packages/ui/index.ts (1)</summary><blockquote>

`13-13`: **BrandBadge 컴포넌트 내보내기에 공백이 빠졌어요! 🔍**

새로운 BrandBadge 컴포넌트를 내보내는 코드가 추가되었네요. 아주 잘했어요! 하지만 작은 부분에 신경써보면, `BrandBadge}` 뒤에 공백이 빠져있어요. 다른 export 문들과 일관성을 맞추기 위해 공백을 추가해주는 게 좋을 것 같아요.

```diff
-export { default as BrandBadge} from './src/BrandBadge/BrandBadge'
+export { default as BrandBadge } from './src/BrandBadge/BrandBadge';
```

그리고 세미콜론(;)도 추가하면 다른 코드 줄과 일치하게 되어 더 일관성 있는 코드가 된답니다!

</blockquote></details>
<details>
<summary>apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx (1)</summary><blockquote>

`8-19`: **마이페이지 정보 목록이 잘 구성되었어요!**

`MyInfoList` 컴포넌트를 아주 잘 구성해주셨어요! 사용자 정보를 보여주는 `MyInfo` 컴포넌트를 맨 위에 배치하고, 그 아래에 구분선 역할을 하는 `Spacer`를 넣고, 그 다음에 고객지원과 공지사항 항목을 `Column`으로 감싸서 세로로 배치했네요.

각 메뉴 항목에는 적절한 아이콘을 사용해서 직관적으로 이해할 수 있게 만들어주셨어요. 헤드셋 아이콘은 고객지원을, 확성기 아이콘은 공지사항을 나타내는 것이 아주 적절해요!

한 가지 작은 제안이 있어요. `ListItem` 컴포넌트에 `onClick` 핸들러를 추가해서 각 항목을 클릭했을 때 해당 페이지로 이동할 수 있게 하면 더 좋을 것 같아요. 지금은 개발 중이니까 이렇게 해도 괜찮지만, 나중에 기능을 추가할 수 있도록 준비해두면 좋을 것 같아요. 🌱

```diff
<Column gap={4}>
-  <ListItem icon={IconHeadset} title="고객지원" />
-  <ListItem icon={IconMegaphone} title="공지사항" />
+  <ListItem 
+    icon={IconHeadset} 
+    title="고객지원" 
+    onClick={() => {
+      // 고객지원 페이지로 이동하는 로직
+    }} 
+  />
+  <ListItem 
+    icon={IconMegaphone} 
+    title="공지사항" 
+    onClick={() => {
+      // 공지사항 페이지로 이동하는 로직
+    }} 
+  />
</Column>
```

</blockquote></details>
<details>
<summary>apps/mobile/src/components/my/ListItem/ListItem.tsx (2)</summary><blockquote>

`13-17`: **alert 대신 디자인 시스템의 알림 컴포넌트 활용 고려**
현재 클릭 시 `alert('추후 개발 예정입니다.')`를 사용하고 있는데, 모바일 환경에서는 네이티브 모달이나 디자인 시스템의 토스트 컴포넌트를 활용해 일관된 UX를 제공하는 것이 좋아요.

---

`33-41`: **StyledListItem에 클릭성 강조 및 시맨틱 향상**
`styled.div` 대신 `styled.button`을 사용하거나 아래와 같이 커서 및 버튼 속성을 추가해 사용자 피드백을 강화해보세요:
```diff
- const StyledListItem = styled.div`
+ const StyledListItem = styled.button.attrs({ type: 'button' })`
   ${flex({
     flexDirection: 'row',
     alignItems: 'center',
     justifyContent: 'space-between',
   })}
   width: 100%;
   padding: 8px 0px;
+  cursor: pointer;
+  background: none;
+  border: none;
+  text-align: left;
`;
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

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

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between d56179c41fe7ce818912a4d461ac18f78af5af4a and 8a81b4b11fac90804a7bbefef0fb29a569f0964d.

</details>

<details>
<summary>📒 Files selected for processing (9)</summary>

* `apps/mobile/src/app/my/page.tsx` (1 hunks)
* `apps/mobile/src/components/my/ListItem/ListItem.tsx` (1 hunks)
* `apps/mobile/src/components/my/MyInfo/MyInfo.tsx` (1 hunks)
* `apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx` (1 hunks)
* `packages/icon/index.ts` (1 hunks)
* `packages/icon/src/IconHeadset.tsx` (1 hunks)
* `packages/icon/src/IconMegaphone.tsx` (1 hunks)
* `packages/ui/index.ts` (1 hunks)
* `packages/ui/src/BrandBadge/BrandBadge.tsx` (1 hunks)

</details>

<details>
<summary>🔇 Additional comments (13)</summary><blockquote>

<details>
<summary>packages/icon/src/IconMegaphone.tsx (1)</summary>

`1-14`: **아이콘 컴포넌트가 깔끔하게 만들어졌어요! 👍**

이 확성기(메가폰) 아이콘은 정말 잘 구현되었네요! SVG 속성들도 적절하게 설정되어 있고, 다른 SVG 속성들도 {...props}를 통해 전달할 수 있도록 해주셨어요. 이렇게 하면 나중에 색상이나 크기를 변경하고 싶을 때 쉽게 수정할 수 있어요.

한 가지 작은 팁을 드리자면, 나중에 이 아이콘의 색상을 쉽게 변경할 수 있도록 stroke 색상을 props로 받을 수도 있어요. 하지만 현재 구현도 충분히 좋습니다!

```jsx
// 이런 식으로 확장할 수도 있어요 (선택 사항)
const IconMegaphone = ({ color = "#686868", ...props }: SVGProps<SVGSVGElement> & { color?: string }) => (
  <svg viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
    <path
      d="M7.7824 7.07598C11.0308 6.18131 18.0616 4 18.0616 4V17.6223C18.0616 17.6223 11.4702 14.9857 7.7824 13.4611M7.7824 7.07598C4 7.07639 6.19713 7.07598 4 7.07598V12.7046L4.75648 13.4611V18H7.7824V13.4611M7.7824 7.07598V13.4611"
      stroke={color}
      strokeWidth="1.51296"
    />
  </svg>
);
```

</details>
<details>
<summary>packages/icon/index.ts (1)</summary>

`18-19`: **새로운 아이콘 추가가 잘 되었어요!**

안녕하세요! 새로운 아이콘 두 개를 추가해주셨네요! `IconHeadset`과 `IconMegaphone` 아이콘을 기존 패턴에 맞게 잘 추가해주셨어요. 이 아이콘들은 마이페이지의 고객지원과 공지사항 섹션에서 사용될 거예요. 기존 코드 패턴을 따라서 깔끔하게 작성해주셔서 정말 좋아요! 👍

</details>
<details>
<summary>apps/mobile/src/app/my/page.tsx (3)</summary>

`3-8`: **필요한 컴포넌트와 유틸리티를 잘 가져왔어요!**

새로운 마이페이지를 만들기 위해 필요한 컴포넌트와 유틸리티들을 잘 가져왔어요! 특히 `MyInfoList` 컴포넌트를 import 해서 사용한 점이 좋아요. 그리고 디자인 시스템의 `Text` 컴포넌트와 `flex` 유틸리티를 활용하는 것도 아주 훌륭해요. 이렇게 하면 디자인이 일관성 있게 유지될 수 있답니다. 😊

---

`12-18`: **마이페이지 UI가 깔끔하게 구성되었어요!**

마이페이지의 UI를 정말 깔끔하게 구성해주셨어요! 배경색을 `G20`에서 `G0`로 변경하여 더 밝고 깨끗한 느낌을 주셨네요. 그리고 단순한 텍스트 대신 디자인 시스템의 `Text` 컴포넌트를 사용해서 "마이페이지"라는 제목을 표시한 점도 아주 좋아요. 

새로 만든 `MyInfoList` 컴포넌트를 추가해서 사용자 정보와 메뉴 항목들을 보여줄 수 있게 되었어요. 이렇게 컴포넌트를 분리하면 코드를 관리하기가 훨씬 쉬워진답니다! 👏

---

`25-34`: **스타일 컴포넌트가 잘 정의되었어요!**

`StyledMy` 컴포넌트를 만들어서 마이페이지의 스타일을 정의해주셨네요! `flex` 유틸리티를 사용해서 세로 방향으로 컴포넌트들을 배치하고, 시작 부분에 정렬되도록 한 점이 좋아요.

패딩과 간격도 디자인에 맞게 잘 설정해주셨어요. 특히 아래쪽 패딩(`115px`)을 충분히 주어서 하단 푸터와 내용이 겹치지 않도록 배려한 점이 훌륭해요. 이런 세심한 부분이 사용자 경험을 더 좋게 만든답니다! 💖

</details>
<details>
<summary>apps/mobile/src/components/my/MyInfo/MyInfo.tsx (2)</summary>

`1-6`: **필요한 컴포넌트들을 잘 가져왔어요!**

사용자 정보를 보여주는 `MyInfo` 컴포넌트를 만들기 위해 필요한 요소들을 잘 가져왔어요! 디자인 시스템의 색상(`color`), 아이콘(`IconArrow`), UI 컴포넌트들(`BrandBadge`, `Column`, `Row`, `Text`)과 유틸리티(`flex`)를 모두 가져와서 잘 활용하셨네요. 이렇게 디자인 시스템의 요소들을 사용하면 일관된 디자인을 유지할 수 있어요. 정말 잘했어요! 😊

---

`28-32`: **스타일 컴포넌트가 잘 정의되었어요!**

`StyledMyInfo` 컴포넌트의 스타일을 아주 깔끔하게 정의해주셨어요! `flex` 유틸리티를 사용해서 가로 방향으로 요소들을 배치하고, 가운데 정렬하고, 양쪽 끝에 요소들이 위치하도록 `space-between`을 사용한 점이 좋아요.

높이를 `51px`로 고정하고 너비를 `100%`로 설정해서 일관된 크기를 유지할 수 있게 했네요. 이렇게 하면 디자인이 깔끔하게 유지될 수 있어요. 잘했어요! 👍

</details>
<details>
<summary>apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx (3)</summary>

`1-7`: **필요한 컴포넌트와 유틸리티를 잘 가져왔어요!**

`MyInfoList` 컴포넌트를 만들기 위해 필요한 요소들을 잘 가져왔어요! 디자인 시스템의 색상(`color`), 방금 만든 `MyInfo` 컴포넌트, 그리고 `ListItem` 컴포넌트와 아이콘들(`IconHeadset`, `IconMegaphone`)을 가져와서 잘 활용하셨네요. `Column` 컴포넌트도 가져와서 세로 방향으로 아이템들을 배치할 수 있게 준비하셨고요. 

모든 필요한 요소들을 깔끔하게 가져와서 정말 잘했어요! 😊

---

`23-25`: **스타일 컴포넌트가 잘 정의되었어요!**

`StyledMyInfoList` 컴포넌트의 스타일을 아주 간단하고 깔끔하게 정의해주셨어요! 너비를 `100%`로 설정해서 부모 컨테이너의 전체 너비를 사용할 수 있게 했네요. 이렇게 하면 모바일 화면에서 내용이 가로로 꽉 차서 보기 좋게 표시될 거예요. 잘했어요! 👏

---

`27-35`: **구분선 역할을 하는 Spacer가 잘 만들어졌어요!**

`Spacer` 컴포넌트를 만들어서 사용자 정보와 메뉴 항목들 사이에 시각적인 구분을 해주셨네요! 너비를 `calc(100% + 36px)`로 설정하고 `left: -18px`를 적용해서 화면 전체 너비로 확장되도록 한 점이 아주 좋아요. 이렇게 하면 패딩이 있는 컨테이너 안에서도 구분선이 화면 끝까지 확장될 수 있어요.

높이는 `10px`로 설정하고 배경색은 연한 회색(`G10`)을 사용해서 미묘하면서도 확실한 구분을 줬네요. 그리고 위아래 여백(`margin-top`, `margin-bottom`)도 적절하게 설정해서 시각적으로 잘 분리되도록 했어요.

이런 세심한 디테일이 사용자 경험을 더 좋게 만든답니다! 정말 잘했어요! 💖

</details>
<details>
<summary>apps/mobile/src/components/my/ListItem/ListItem.tsx (3)</summary>

`1-6`: **컴포넌트 모듈 임포트가 적절합니다.**
컴포넌트에 필요한 모듈이 모두 사용되며, 불필요한 임포트가 보이지 않아 깔끔해요.

---

`8-11`: **Props 타입 정의가 명확합니다.**
`icon`을 `React.ComponentType<SVGProps<SVGSVGElement>>`로 지정해 SVG 컴포넌트를 엄격하게 받도록 한 점이 좋네요.

---

`31-31`: **`export default ListItem;`은 적절합니다.**
컴포넌트 익스포트 방식이 명확하고, 다른 파일에서 불러올 때 문제가 없어요.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-08T07:01:26Z
user: login: MinjuN07
body: 와 홍섭님 개발속도가 엄청 빨라요!!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T07:13:56Z

Review comments:
diff_hunk: @@ -0,0 +1,31 @@
+import { color } from '@merried/design-system';
+import { flex } from '@merried/utils';
+import styled from 'styled-components';
+import Text from '../Text/Text';
+
+interface BradnBadgeProps {
+  type: 'KAKAO' | 'NAVER';
+}
path: packages/ui/src/BrandBadge/BrandBadge.tsx
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**인터페이스 이름에 오타가 있어요! 🔤**

인터페이스 이름이 `BradnBadgeProps`로 되어 있는데, 'Brand'의 'd'와 'n'이 바뀌어 있어요. 올바른 이름은 `BrandBadgeProps`가 되어야 해요. 

이런 작은 오타는 나중에 코드를 이해하기 어렵게 만들 수 있어요. 특히 다른 개발자들이 이 코드를 볼 때 혼란스러울 수 있답니다.

```diff
-interface BradnBadgeProps {
+interface BrandBadgeProps {
  type: 'KAKAO' | 'NAVER';
}
```




<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **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.

`````suggestion
interface BrandBadgeProps {
  type: 'KAKAO' | 'NAVER';
}
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commit 999c1b7
created_at: 2025-05-08T07:01:25Z
author_association: NONE
diff_hunk: @@ -0,0 +1,31 @@
+import { color } from '@merried/design-system';
+import { flex } from '@merried/utils';
+import styled from 'styled-components';
+import Text from '../Text/Text';
+
+interface BradnBadgeProps {
+  type: 'KAKAO' | 'NAVER';
+}
+
+const BrandBadge = ({ type }: BradnBadgeProps) => {
+  return (
+    <StyledBrandBadge $badgeType={type}>
+      <Text fontType="P4" color={type === 'NAVER' ? color.G0 : color.G400}>
+        {type === 'NAVER' ? '네이버' : '카카오'}
+      </Text>
+    </StyledBrandBadge>
+  );
+};
path: packages/ui/src/BrandBadge/BrandBadge.tsx
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**BrandBadge 컴포넌트가 잘 구현되었어요, 하지만 오타가 있어요! 🎯**

이 컴포넌트는 두 가지 브랜드(네이버와 카카오)를 표시할 수 있고, 각 브랜드마다 다른 색상과 텍스트를 보여주네요! 참 잘 만들었어요.

하지만 10번 줄에서 `BradnBadgeProps` 인터페이스를 사용하고 있는데, 이름에 오타가 있어요. 인터페이스 이름을 올바르게 수정한 후에는 여기도 수정해야 해요.

```diff
-const BrandBadge = ({ type }: BradnBadgeProps) => {
+const BrandBadge = ({ type }: BrandBadgeProps) => {
  return (
    <StyledBrandBadge $badgeType={type}>
      <Text fontType="P4" color={type === 'NAVER' ? color.G0 : color.G400}>
        {type === 'NAVER' ? '네이버' : '카카오'}
      </Text>
    </StyledBrandBadge>
  );
};
```




<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **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.

`````suggestion
const BrandBadge = ({ type }: BrandBadgeProps) => {
  return (
    <StyledBrandBadge $badgeType={type}>
      <Text fontType="P4" color={type === 'NAVER' ? color.G0 : color.G400}>
        {type === 'NAVER' ? '네이버' : '카카오'}
      </Text>
    </StyledBrandBadge>
  );
};
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commit 999c1b7
created_at: 2025-05-08T07:01:25Z
author_association: NONE
diff_hunk: @@ -0,0 +1,31 @@
+import { color } from '@merried/design-system';
+import { flex } from '@merried/utils';
+import styled from 'styled-components';
+import Text from '../Text/Text';
+
+interface BradnBadgeProps {
+  type: 'KAKAO' | 'NAVER';
+}
+
+const BrandBadge = ({ type }: BradnBadgeProps) => {
+  return (
+    <StyledBrandBadge $badgeType={type}>
+      <Text fontType="P4" color={type === 'NAVER' ? color.G0 : color.G400}>
+        {type === 'NAVER' ? '네이버' : '카카오'}
+      </Text>
+    </StyledBrandBadge>
+  );
+};
+
+export default BrandBadge;
+
+const StyledBrandBadge = styled.div<{ $badgeType: BradnBadgeProps['type'] }>`
+  ${flex({ alignItems: 'center', justifyContent: 'center' })}
+  width: 60px;
+  height: 28px;
+  background: ${({ $badgeType }) =>
+    $badgeType === 'NAVER' ? 'rgba(4, 199, 91, 0.6)' : 'rgba(250, 225, 0, 0.6)'};
+  border-radius: 999px;
+  border: 1px solid
+    ${({ $badgeType }) => ($badgeType === 'NAVER' ? '#04C75B' : '#fae100')};
+`;
path: packages/ui/src/BrandBadge/BrandBadge.tsx
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**StyledBrandBadge 컴포넌트에도 오타가 있어요! 🧩**

StyledBrandBadge 컴포넌트에서도 `BradnBadgeProps` 인터페이스를 사용하고 있는데, 여기도 인터페이스 이름의 오타를 수정해주어야 해요.

또한, 스타일 코드 자체는 정말 잘 작성되었어요! `$badgeType`에 달러($) 기호를 사용한 것은 styled-components에서 transient prop(DOM에 전달되지 않는 prop)을 표시하는 좋은 방법이에요.

```diff
-const StyledBrandBadge = styled.div<{ $badgeType: BradnBadgeProps['type'] }>`
+const StyledBrandBadge = styled.div<{ $badgeType: BrandBadgeProps['type'] }>`
  ${flex({ alignItems: 'center', justifyContent: 'center' })}
  width: 60px;
  height: 28px;
  background: ${({ $badgeType }) =>
    $badgeType === 'NAVER' ? 'rgba(4, 199, 91, 0.6)' : 'rgba(250, 225, 0, 0.6)'};
  border-radius: 999px;
  border: 1px solid
    ${({ $badgeType }) => ($badgeType === 'NAVER' ? '#04C75B' : '#fae100')};
`;
```




<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **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.

`````suggestion
const StyledBrandBadge = styled.div<{ $badgeType: BrandBadgeProps['type'] }>`
  ${flex({ alignItems: 'center', justifyContent: 'center' })}
  width: 60px;
  height: 28px;
  background: ${({ $badgeType }) =>
    $badgeType === 'NAVER' ? 'rgba(4, 199, 91, 0.6)' : 'rgba(250, 225, 0, 0.6)'};
  border-radius: 999px;
  border: 1px solid
    ${({ $badgeType }) => ($badgeType === 'NAVER' ? '#04C75B' : '#fae100')};
`;
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commit 999c1b7
created_at: 2025-05-08T07:01:25Z
author_association: NONE
diff_hunk: @@ -0,0 +1,32 @@
+import { color } from '@merried/design-system';
+import { IconArrow } from '@merried/icon';
+import { BrandBadge, Column, Row, Text } from '@merried/ui';
+import { flex } from '@merried/utils';
+import styled from 'styled-components';
+
+const MyInfo = () => {
+  return (
+    <StyledMyInfo onClick={() => {}}>
+      <Column gap={6}>
+        <Row gap={8} alignItems="center">
+          <Text fontType="H3_140per" color={color.G900}>
+            박강원님
+          </Text>
+          <BrandBadge type="NAVER" />
+        </Row>
+        <Text fontType="P3" color={color.G60}>
+          pkw0227@gmail.com
+        </Text>
+      </Column>
+      <IconArrow width={18} height={18} direction="left" />
+    </StyledMyInfo>
+  );
+};
path: apps/mobile/src/components/my/MyInfo/MyInfo.tsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**사용자 정보 컴포넌트가 깔끔하게 구현되었어요!**

`MyInfo` 컴포넌트를 아주 깔끔하게 만들어주셨어요! 사용자의 이름과 이메일을 보여주고, 네이버 로그인을 했음을 나타내는 브랜드 뱃지도 추가해주셨네요. 레이아웃도 `Column`과 `Row`를 적절히 사용해서 잘 구성해주셨어요.

한 가지 작은 제안이 있어요. 현재는 사용자 정보가 하드코딩되어 있는데, 나중에는 props로 받아서 사용하거나 데이터를 가져와서 보여주면 더 좋을 것 같아요. 지금은 개발 중이니까 이렇게 해도 괜찮지만, 나중에 실제 데이터를 사용할 수 있도록 준비해두면 좋을 것 같아요. 🌱

또한, `onClick` 핸들러가 비어있어요. 이것은 아마도 나중에 기능을 추가하기 위한 자리 표시자일 거예요. 나중에 사용자 정보 수정 페이지로 이동하는 등의 기능을 추가하면 좋을 것 같아요.

```diff
-const MyInfo = () => {
+interface MyInfoProps {
+  name: string;
+  email: string;
+  brandType: 'NAVER' | 'KAKAO';
+  onClick?: () => void;
+}
+
+const MyInfo = ({ name, email, brandType, onClick }: MyInfoProps) => {
  return (
-    <StyledMyInfo onClick={() => {}}>
+    <StyledMyInfo onClick={onClick}>
      <Column gap={6}>
        <Row gap={8} alignItems="center">
          <Text fontType="H3_140per" color={color.G900}>
-            박강원님
+            {name}
          </Text>
-          <BrandBadge type="NAVER" />
+          <BrandBadge type={brandType} />
        </Row>
        <Text fontType="P3" color={color.G60}>
-          pkw0227@gmail.com
+          {email}
        </Text>
      </Column>
      <IconArrow width={18} height={18} direction="left" />
    </StyledMyInfo>
  );
};
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **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.

`````suggestion
interface MyInfoProps {
  name: string;
  email: string;
  brandType: 'NAVER' | 'KAKAO';
  onClick?: () => void;
}

const MyInfo = ({ name, email, brandType, onClick }: MyInfoProps) => {
  return (
    <StyledMyInfo onClick={onClick}>
      <Column gap={6}>
        <Row gap={8} alignItems="center">
          <Text fontType="H3_140per" color={color.G900}>
            {name}
          </Text>
          <BrandBadge type={brandType} />
        </Row>
        <Text fontType="P3" color={color.G60}>
          {email}
        </Text>
      </Column>
      <IconArrow width={18} height={18} direction="left" />
    </StyledMyInfo>
  );
};
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-08T07:01:25Z
author_association: NONE
diff_hunk: @@ -0,0 +1,41 @@
+import { color } from '@merried/design-system';
+import { IconArrow } from '@merried/icon';
+import { Row, Text } from '@merried/ui';
+import { flex } from '@merried/utils';
+import { SVGProps } from 'react';
+import styled from 'styled-components';
+
+interface ListItemProps {
+  icon: React.ComponentType<SVGProps<SVGSVGElement>>;
+  title: string;
+}
+
+const ListItem = ({ icon: Icon, title }: ListItemProps) => {
+  const handleItemClick = () => {
+    alert('추후 개발 예정입니다.');
+  };
+
+  return (
+    <StyledListItem onClick={handleItemClick}>
+      <Row gap={8} alignItems="center">
+        <Icon width={22} height={22} />
+        <Text fontType="P3" color={color.G300}>
+          {title}
+        </Text>
+      </Row>
+      <IconArrow width={18} height={18} direction="left" />
+    </StyledListItem>
path: apps/mobile/src/components/my/ListItem/ListItem.tsx
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**접근성(Accessibility) 및 시맨틱 개선 제안**
- 현재 `StyledListItem`이 `<div>`로 구현되어 있어 키보드 접근성이 부족합니다. `role="button"`, `tabIndex={0}`, `onKeyDown` 핸들러 추가하거나 `<button>` 요소 사용을 권장해요.  
- 클릭 가능하다는 시각적 피드백을 위해 `cursor: pointer`도 함께 적용해주세요.  
- 디자인 시안에서 리스트 아이템의 화살표 방향이 왼쪽(left)인지 오른쪽(right)인지 한번 확인 부탁드립니다.

---

StyledListItem 정의와 사용 방식을 먼저 살펴볼게요. 아래 스크립트를 실행해서 파일 상단의 import 구문과 StyledListItem 선언부를 확인해 주세요.

---

🏁 Script executed:

```shell
sed -n '1,50p' apps/mobile/src/components/my/ListItem/ListItem.tsx
```

Length of output: 1069

---



</details>

**접근성·시맨틱 개선을 위한 꼭 필요한 수정사항 안내**

StyledListItem이 현재 `<div>`로만 구현되어 있어 키보드 사용자가 접근하기 어렵고, 클릭 가능한 요소라는 시각적 힌트도 부족해요. 아래와 같이 변경해주세요:

• 파일 위치  
  - apps/mobile/src/components/my/ListItem/ListItem.tsx  

• 변경 요점  
  1. 요소를 `<button>`으로 전환하거나, `<div>`를 유지할 경우 `role="button"`, `tabIndex={0}`, `onKeyDown` 핸들러 추가  
  2. 클릭 가능한 영역임을 알려줄 `cursor: pointer` 스타일 적용  
  3. 디자인 시안에 맞춰 화살표 방향(`direction` prop)이 왼쪽인지 오른쪽인지 최종 확인  

• 예시 diff  

```diff
- const ListItem = ({ icon: Icon, title }: ListItemProps) => {
-   return (
-     <StyledListItem onClick={handleItemClick}>
+ const ListItem = ({ icon: Icon, title }: ListItemProps) => {
+   return (
+     <StyledListItem
+       as="button"                     // ① button으로 렌더링
+       onClick={handleItemClick}
+       tabIndex={0}                    // ② 키보드 포커스 허용
+       onKeyDown={e => {
+         if (e.key === 'Enter' || e.key === ' ') {
+           handleItemClick();          // ③ Enter·Space 키로도 클릭 가능
+         }
+       }}
+     >
```

```diff
- const StyledListItem = styled.div`
+ const StyledListItem = styled.button`
   ${flex({ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' })}
   width: 100%;
   padding: 8px 0px;
+  cursor: pointer;                  // ④ 클릭 가능함을 시각적으로 표시
`;
```

• 화살표 방향  
  - 현재 `direction="left"`로 되어 있는데, 디자인 시안과 일치하는지 다시 한번 확인 부탁드려요.  

위 항목들을 반영하시면 접근성은 물론 시맨틱 측면에서도 훨씬 개선됩니다! 

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **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.

`````suggestion
// apps/mobile/src/components/my/ListItem/ListItem.tsx

const ListItem = ({ icon: Icon, title }: ListItemProps) => {
  const handleItemClick = useCallback(() => {
    // existing click logic…
  }, []);

  return (
    <StyledListItem
      as="button"                     // ① render as <button>
      onClick={handleItemClick}
      tabIndex={0}                    // ② allow keyboard focus
      onKeyDown={e => {               // ③ activate on Enter/Space
        if (e.key === 'Enter' || e.key === ' ') {
          handleItemClick();
        }
      }}
    >
      <Row gap={8} alignItems="center">
        <Icon width={22} height={22} />
        <Text fontType="P3" color={color.G300}>
          {title}
        </Text>
      </Row>
      <IconArrow width={18} height={18} direction="left" />
    </StyledListItem>
  );
};

const StyledListItem = styled.button`       // ⬅️ changed from styled.div
  ${flex({ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' })}
  width: 100%;
  padding: 8px 0px;
  cursor: pointer;                         // ④ visual cue for clickable
`;
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-08T07:01:25Z
author_association: NONE

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-08T06:58:23Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: rate limited by coderabbit.ai -->

> [!WARNING]
> ## Rate limit exceeded
> 
> @junghongseop has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait **12 minutes and 42 seconds** before requesting another review.
> 
> <details>
> <summary>⌛ How to resolve this issue?</summary>
> 
> After the wait time has elapsed, a review can be triggered using the `@coderabbitai review` command as a PR comment. Alternatively, push new commits to this PR.
> 
> We recommend that you space out your commits to avoid hitting the rate limit.
> 
> </details>
> 
> 
> <details>
> <summary>🚦 How do rate limits work?</summary>
> 
> CodeRabbit enforces hourly rate limits for each developer per organization.
> 
> Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.
> 
> Please see our [FAQ](https://docs.coderabbit.ai/faq) for further information.
> 
> </details>
> 
> <details>
> <summary>📥 Commits</summary>
> 
> Reviewing files that changed from the base of the PR and between 999c1b7a53ecf671e906aa441fa28c8800ac06d6 and 92d7784a1c91dfff6f7381e18f6e88e11459d47c.
> 
> </details>
> 
> <details>
> <summary>📒 Files selected for processing (3)</summary>
> 
> * `apps/mobile/src/app/my/page.tsx` (1 hunks)
> * `apps/mobile/src/components/my/MyInfo/MyInfo.tsx` (1 hunks)
> * `apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx` (1 hunks)
> 
> </details>

<!-- end of auto-generated comment: rate limited by coderabbit.ai -->
<!-- walkthrough_start -->

"""
## Walkthrough

이번 변경에서는 마이페이지의 UI 구조와 스타일이 개선되었고, 사용자 정보와 리스트 아이템을 보여주는 새로운 컴포넌트들이 추가되었습니다. 또한, 브랜드 뱃지와 고객지원/공지사항 아이콘 등 디자인 시스템 관련 컴포넌트와 아이콘들이 새롭게 도입되었습니다.

## Changes

| 파일/경로                                                         | 변경 요약                                                                                      |
|-------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|
| apps/mobile/src/app/my/page.tsx                                   | 마이페이지 UI 구조 및 스타일 개선, `MyInfoList` 컴포넌트 추가, 레이아웃 및 색상 변경             |
| apps/mobile/src/components/my/ListItem/ListItem.tsx               | 새로운 `ListItem` 컴포넌트 추가: 아이콘, 제목, 클릭 시 알림 기능 포함                           |
| apps/mobile/src/components/my/MyInfo/MyInfo.tsx                   | 새로운 `MyInfo` 컴포넌트 추가: 사용자 이름, 이메일, 브랜드 뱃지, 화살표 아이콘 등 표시           |
| apps/mobile/src/components/my/MyInfoList/MyInfoList.tsx           | 새로운 `MyInfoList` 컴포넌트 추가: 사용자 정보와 리스트 아이템들을 정렬, 구분선 포함             |
| packages/icon/index.ts                                            | `IconHeadset`, `IconMegaphone` 아이콘 export 추가                                              |
| packages/icon/src/IconHeadset.tsx                                 | 새로운 헤드셋 아이콘 컴포넌트 추가                                                             |
| packages/icon/src/IconMegaphone.tsx                               | 새로운 메가폰 아이콘 컴포넌트 추가                                                             |
| packages/ui/index.ts                                              | `BrandBadge` 컴포넌트 export 추가                                                              |
| packages/ui/src/BrandBadge/BrandBadge.tsx                         | 새로운 브랜드 뱃지 컴포넌트 추가: KAKAO, NAVER 타입 지원, 동적 스타일 적용                      |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant MyPage
    participant MyInfoList
    participant MyInfo
    participant ListItem

    User->>MyPage: 마이페이지 진입
    MyPage->>MyInfoList: MyInfoList 렌더링
    MyInfoList->>MyInfo: 사용자 정보 표시
    MyInfoList->>ListItem: 고객지원, 공지사항 리스트 아이템 렌더링
    User->>ListItem: 리스트 아이템 클릭
    ListItem->>User: "추후 개발 예정입니다." 알림 표시
```

## Possibly related PRs

- WillYouMerryMe/getting-married#27: 기존 마이페이지 컴포넌트를 단순 텍스트에서 UI 구조와 스타일 개선, 추가 컴포넌트 도입으로 확장한 PR입니다.

## Suggested reviewers

- MinjuN07

## Poem

> 🎈  
> 새로운 뱃지와 아이콘이 반짝반짝,  
> 마이페이지가 예쁘게 변신했어요!  
> 사용자 정보, 고객지원, 공지사항까지  
> 한눈에 쏙 들어오는 구조로  
> 모두가 쉽게 사용할 수 있길 바라며,  
> 다음 변화도 기대하며 두근두근!  
> 🌟
"""

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


<!-- 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= -->

<!-- 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=WillYouMerryMe/getting-married&utm_content=46):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `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 generate unit testing code for this file.`
  -	`@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 generate unit testing code.`
  - `@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 -->
author_association: NONE
user: login: akns27
created_at: 2025-05-08T07:06:00Z
body: 홍섭님 짱이네요!
author_association: CONTRIBUTOR