diff --git a/frontend/src/components/settings/settings-navigation-item.stories.tsx b/frontend/src/components/settings/settings-navigation-item.stories.tsx
deleted file mode 100644
index 66c0f13..0000000
--- a/frontend/src/components/settings/settings-navigation-item.stories.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { ListGroup } from '@/components/ui/list-group'
-import { SettingsNavigationItem } from '@/components/settings/settings-navigation-item'
-import type { Meta, StoryObj } from '@storybook/react-vite'
-
-const meta = {
- title: 'Settings/SettingsNavigationItem',
- component: SettingsNavigationItem,
- tags: ['autodocs'],
- args: {
- label: '알림 설정',
- onClick: () => {},
- },
- // 항목은 ListGroup(둥근 배경·구분선 컨텍스트) 안에서 쓰이므로 감싸서 실제 모습을 보여준다.
- decorators: [
- (Story) => (
-
-
-
-
-
- ),
- ],
-} satisfies Meta
-
-export default meta
-
-type Story = StoryObj
-
-export const Default: Story = {}
-
-export const WithoutDivider: Story = {
- args: { withDivider: false },
-}
-
-export const LongText: Story = {
- args: { label: '오랜만에 연락한 사람에게 보낼 안부 리마인더 알림 설정' },
-}
diff --git a/frontend/src/components/settings/settings-navigation-item.tsx b/frontend/src/components/settings/settings-navigation-item.tsx
deleted file mode 100644
index 438b9c0..0000000
--- a/frontend/src/components/settings/settings-navigation-item.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { ChevronRight } from 'lucide-react'
-import { ListGroupItem } from '@/components/ui/list-group-item'
-
-export function SettingsNavigationItem({
- label,
- onClick,
- withDivider = true,
-}: {
- label: string
- onClick: () => void
- withDivider?: boolean
-}) {
- return (
-
-
-
- )
-}
diff --git a/frontend/src/components/ui/navigation-row.stories.tsx b/frontend/src/components/ui/navigation-row.stories.tsx
new file mode 100644
index 0000000..d87445e
--- /dev/null
+++ b/frontend/src/components/ui/navigation-row.stories.tsx
@@ -0,0 +1,47 @@
+import { ListGroup } from '@/components/ui/list-group'
+import { NavigationRow } from '@/components/ui/navigation-row'
+import type { Meta, StoryObj } from '@storybook/react-vite'
+
+const meta = {
+ title: 'UI/NavigationRow',
+ component: NavigationRow,
+ tags: ['autodocs'],
+ args: {
+ label: '프로필 수정',
+ onClick: () => {},
+ },
+ // 행은 ListGroup(둥근 배경·구분선 컨텍스트) 안에서 쓰이므로 감싸서 실제 모습을 보여준다.
+ decorators: [
+ (Story) => (
+
+
+
+
+
+ ),
+ ],
+} satisfies Meta
+
+export default meta
+
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const Destructive: Story = {
+ args: { label: '인물 삭제', tone: 'destructive', withDivider: false },
+}
+
+export const WithoutDivider: Story = {
+ args: { withDivider: false },
+}
+
+export const Disabled: Story = {
+ args: { label: '인물 삭제', tone: 'destructive', disabled: true },
+}
+
+export const LongText: Story = {
+ args: {
+ label: '오랜만에 연락한 사람에게 보낼 안부 리마인더를 지금 설정하기',
+ },
+}
diff --git a/frontend/src/components/ui/navigation-row.tsx b/frontend/src/components/ui/navigation-row.tsx
new file mode 100644
index 0000000..2fed6b2
--- /dev/null
+++ b/frontend/src/components/ui/navigation-row.tsx
@@ -0,0 +1,49 @@
+import { ChevronRight } from 'lucide-react'
+import { ListGroupItem } from '@/components/ui/list-group-item'
+
+// 오른쪽 chevron을 가진 라벨 행 버튼. label + onClick만 받고 라우팅/도메인은 호출부가 소유한다.
+// tone='destructive'는 인물 삭제 등 되돌릴 수 없는 동작의 시각 경고(라벨·chevron을 destructive 색)로만 쓴다.
+// 터치 앱이라 hover(포인터 기기)와 active(누름) 피드백을 함께 유지한다.
+export function NavigationRow({
+ label,
+ onClick,
+ tone = 'default',
+ withDivider = true,
+ disabled = false,
+}: {
+ label: string
+ onClick: () => void
+ tone?: 'default' | 'destructive'
+ withDivider?: boolean
+ disabled?: boolean
+}) {
+ const isDestructive = tone === 'destructive'
+
+ return (
+
+
+
+ )
+}
diff --git a/frontend/src/stackflow/activities/person/person-profile-view.tsx b/frontend/src/stackflow/activities/person/person-profile-view.tsx
index 5ce9ac1..7d65690 100644
--- a/frontend/src/stackflow/activities/person/person-profile-view.tsx
+++ b/frontend/src/stackflow/activities/person/person-profile-view.tsx
@@ -9,6 +9,7 @@ import { MonogramAvatar } from '@/components/ui/monogram-avatar'
import { ListGroup } from '@/components/ui/list-group'
import { ListGroupItem } from '@/components/ui/list-group-item'
import { ListGroupLabel } from '@/components/ui/list-group-label'
+import { NavigationRow } from '@/components/ui/navigation-row'
import { StatusMessage } from '@/components/ui/status-message'
import { TagChip } from '@/components/ui/tag-chip'
import { optimizedImageUrl } from '@/lib/image-url'
@@ -224,37 +225,21 @@ export function PersonProfileView({
작업
-
-
-
-
-
-
-
-
-
+ push('Record', { personId })}
+ />
+ push('PersonEdit', { personId })}
+ />
+ del.setOpen(true)}
+ />
diff --git a/frontend/src/stackflow/tabs/settings-tab.tsx b/frontend/src/stackflow/tabs/settings-tab.tsx
index 6ef7fbd..e8222da 100644
--- a/frontend/src/stackflow/tabs/settings-tab.tsx
+++ b/frontend/src/stackflow/tabs/settings-tab.tsx
@@ -3,10 +3,10 @@ import { useFlow } from '@stackflow/react'
import { RotateCcw } from 'lucide-react'
import { useState } from 'react'
import { MongleLogo } from '@/components/brand/mongle-logo'
-import { SettingsNavigationItem } from '@/components/settings/settings-navigation-item'
import { useTheme } from '@/components/theme-provider'
import { Button } from '@/components/ui/button'
import { ConfirmPopup } from '@/components/ui/confirm-popup'
+import { NavigationRow } from '@/components/ui/navigation-row'
import { PageTitle } from '@/components/ui/page-title'
import { ListGroup } from '@/components/ui/list-group'
import { ListGroupItem } from '@/components/ui/list-group-item'
@@ -48,11 +48,11 @@ export function SettingsTab() {
- push('HomeSettings', {})}
/>
- push('TagSettings', {})}