'use client'; import { useState, useTransition } from 'react'; import { FoxButton } from '@fox/core/components/fox-button'; import { FoxButtonGroup } from '@fox/core/components/fox-button-group'; import { FoxIconButton } from '@fox/core/components/fox-icon-button'; import { FoxPencilSimpleIcon, FoxTrashIcon } from '@fox/core/icons'; import { useFeedback } from '@/app/_hooks/use-feedback'; import type { BoardPost, BoardType } from '@/lib/domain/board-post'; import { deleteBoardPostAction } from '../_actions'; import { BoardPostFormModal } from './board-post-form-modal'; interface BoardRowActionsProps { boardType: BoardType; post: BoardPost; } /** * 목록 행의 "관리" 셀(시안 A_BOA_006 ④ / 014 ④) — 수정 팝업의 열림 상태만 소유하는 최말단 * 상호작용 경계다(테이블 전체를 클라이언트로 내리지 않기 위해 이 셀만 분리했다). * * 삭제는 시안대로 **확인 얼럿을 거친 뒤** 실행한다. 백엔드는 물리 삭제가 아니라 `DEL_YN='Y'`로 * 표시만 바꾸지만, 관리자 화면에서 다시 볼 방법이 없으므로 사용자에게는 되돌릴 수 없는 동작으로 * 안내한다. * * 시안의 연필·휴지통 아이콘 버튼이다. 버튼은 `components/ui/button`이 아니라 `FoxIconButton`을 * 쓴다 — 아이콘은 스스로 크기를 갖지 않고 감싼 슬롯이 정하는데, 그 슬롯 크기를 실제로 정의하는 * 건 @fox 쪽뿐이다(components/ui는 Tailwind 제거 이후 무스타일이다). */ export function BoardRowActions({ boardType, post }: BoardRowActionsProps) { const { showAlert, hideAlert, showToast } = useFeedback(); const [isEditOpen, setIsEditOpen] = useState(false); const [isDeleting, startDeleting] = useTransition(); function runDelete() { hideAlert(); startDeleting(async () => { const result = await deleteBoardPostAction(boardType, post.id); if (result.status === 'error') { showToast({ variant: 'danger', message: result.message ?? '삭제하지 못했습니다.', }); return; } showToast({ variant: 'success', message: '게시물을 삭제했습니다.' }); }); } function confirmDelete() { showAlert({ variant: 'danger', title: '게시물을 삭제하시겠습니까?', message: `"${post.title}" 게시물을 삭제합니다. 삭제 후에는 되돌릴 수 없습니다.`, actions: ( ), }); } return (
} label="수정" onAction={() => setIsEditOpen(true)} /> } label={isDeleting ? '삭제 중' : '삭제'} disabled={isDeleting} onAction={confirmDelete} /> {isEditOpen && ( setIsEditOpen(false)} /> )}
); }