임동욱 임동욱 08-11
feat: 꾸미기 아이템 삭제 기능 추가
Co-Authored-By: Claude Opus 5 
@eae249ebe51971a1d7ffd7cf4a2e05639e10b8ea
 
app/(protected)/(basic)/decoration-items/_components/decoration-item-row-actions.tsx (added)
+++ app/(protected)/(basic)/decoration-items/_components/decoration-item-row-actions.tsx
@@ -0,0 +1,97 @@
+'use client';
+
+import { useState, useTransition } from 'react';
+import { Button } from '@/components/ui/button';
+import { useFeedback } from '@/app/_hooks/use-feedback';
+import type { DecorationItem } from '@/lib/domain/decoration-item';
+import { deleteDecorationItemAction } from '../_actions';
+import { DecorationItemEditModal } from './decoration-item-edit-modal';
+
+interface DecorationItemRowActionsProps {
+  item: DecorationItem;
+  /** 수정 팝업의 "(총 등록 N개)" 힌트로 그대로 흘려보낸다(현재 유형 전체 등록 건수). */
+  typeTotalCount: number;
+}
+
+/**
+ * 목록 행의 "관리" 셀(시안 ADM_ITM_101) — 수정 팝업 열림 상태만 소유하는 최말단 상호작용
+ * 경계다(테이블 전체를 클라이언트로 내리지 않기 위해 이 셀만 분리했다, admins와 동일 패턴).
+ *
+ * **삭제는 시안대로 확인 얼럿을 거친 뒤 실행한다** — 전역 얼럿(FeedbackProvider)의 actions
+ * 슬롯에 직접 [취소]/[삭제] 버튼을 넣어 구성한다. 삭제는 되돌릴 수 없는 동작이라 얼럿 문구에
+ * 명시한다.
+ *
+ * 시안은 연필·휴지통 아이콘 버튼을 지정하지만 `components/ui/icons/`에 아직 없어(신규 아이콘
+ * 추가는 공용 컴포넌트 신설이라 design 레인 소관) admins와 동일하게 텍스트 버튼으로 대체했다.
+ */
+export function DecorationItemRowActions({
+  item,
+  typeTotalCount,
+}: DecorationItemRowActionsProps) {
+  const { showAlert, hideAlert, showToast } = useFeedback();
+  const [isEditOpen, setIsEditOpen] = useState(false);
+  const [isDeleting, startDeleting] = useTransition();
+
+  function runDelete() {
+    hideAlert();
+    startDeleting(async () => {
+      const result = await deleteDecorationItemAction(item.itemId);
+      if (result.status === 'error') {
+        showToast({
+          variant: 'danger',
+          message: result.message ?? '삭제하지 못했습니다.',
+        });
+        return;
+      }
+      showToast({ variant: 'success', message: '아이템을 삭제했습니다.' });
+    });
+  }
+
+  function confirmDelete() {
+    showAlert({
+      variant: 'danger',
+      title: '아이템을 삭제하시겠습니까?',
+      message: `${item.name}(${item.itemId})을(를) 삭제합니다. 삭제 후에는 되돌릴 수 없습니다.`,
+      actions: (
+        <>
+          <Button type="button" variant="ghost" onClick={hideAlert}>
+            취소
+          </Button>
+          <Button type="button" variant="primary" onClick={runDelete}>
+            삭제
+          </Button>
+        </>
+      ),
+    });
+  }
+
+  return (
+    <div className="flex items-center gap-1">
+      <Button
+        type="button"
+        variant="ghost"
+        size="sm"
+        onClick={() => setIsEditOpen(true)}
+      >
+        수정
+      </Button>
+      <Button
+        type="button"
+        variant="ghost"
+        size="sm"
+        onClick={confirmDelete}
+        disabled={isDeleting}
+      >
+        {isDeleting ? '삭제 중...' : '삭제'}
+      </Button>
+
+      {isEditOpen && (
+        <DecorationItemEditModal
+          item={item}
+          typeTotalCount={typeTotalCount}
+          onClose={() => setIsEditOpen(false)}
+        />
+      )}
+    </div>
+  );
+}
Add a comment
List