/** * ModerationControls - Lock, pin, delete actions for moderators/admins. * Only renders when user has moderator privileges. * Uses ConfirmDialog for destructive actions. * @see specs/prd-web.md Section M7 (Moderation controls) */ 'use client' import { useState } from 'react' import { Lock, LockOpen, PushPin, Trash } from '@phosphor-icons/react' import { cn } from '@/lib/utils' import { ConfirmDialog } from './confirm-dialog' export type ModerationAction = 'lock' | 'unlock' | 'pin' | 'unpin' | 'delete' export interface ModerationActionOptions { scope?: 'category' | 'forum' } interface ModerationControlsProps { isModerator: boolean isLocked?: boolean isPinned?: boolean isAdmin?: boolean pinnedCount?: number onAction: (action: ModerationAction, options?: ModerationActionOptions) => void className?: string } const ACTION_CONFIRMATIONS: Record = { delete: { title: 'Delete Topic', description: 'This will permanently delete this topic and all its replies. This action cannot be undone.', }, lock: { title: 'Lock Topic', description: 'Locking this topic will prevent new replies from being posted.', }, unlock: { title: 'Unlock Topic', description: 'Unlocking this topic will allow new replies again.', }, pin: { title: 'Pin Topic', description: 'This topic will be pinned to the top of the category.', }, unpin: { title: 'Unpin Topic', description: 'This topic will no longer be pinned to the top.', }, } export function ModerationControls({ isModerator, isLocked = false, isPinned = false, isAdmin = false, pinnedCount, onAction, className, }: ModerationControlsProps) { const [pendingAction, setPendingAction] = useState(null) const [pinScope, setPinScope] = useState<'category' | 'forum'>('category') if (!isModerator) return null const handleAction = (action: ModerationAction) => { setPendingAction(action) } const handleConfirm = () => { if (pendingAction) { if (pendingAction === 'pin') { onAction(pendingAction, { scope: pinScope }) } else { onAction(pendingAction) } setPendingAction(null) setPinScope('category') } } const handleCancel = () => { setPendingAction(null) setPinScope('category') } const lockAction = isLocked ? 'unlock' : 'lock' const pinAction = isPinned ? 'unpin' : 'pin' return ( <>
{pendingAction && ( {pendingAction === 'pin' && ( <>
Pin scope
{isAdmin && ( )}
{pinnedCount !== undefined && pinnedCount >= 5 && (

This category has {pinnedCount} pinned topics. Too many pinned topics reduce their effectiveness.

)} )}
)} ) }