'use client'; import { forwardRef, memo, useState, useTransition } from 'react'; import type { SwotItem, SwotCategory } from '@prisma/client'; import { updateSwotItem, deleteSwotItem, duplicateSwotItem } from '@/actions/swot'; interface SwotCardProps { item: SwotItem; sessionId: string; isSelected: boolean; isHighlighted: boolean; isDragging: boolean; linkMode: boolean; onSelect: () => void; } const categoryStyles: Record = { STRENGTH: { ring: 'ring-strength', text: 'text-strength' }, WEAKNESS: { ring: 'ring-weakness', text: 'text-weakness' }, OPPORTUNITY: { ring: 'ring-opportunity', text: 'text-opportunity' }, THREAT: { ring: 'ring-threat', text: 'text-threat' }, }; export const SwotCard = memo( forwardRef( ( { item, sessionId, isSelected, isHighlighted, isDragging, linkMode, onSelect, ...props }, ref ) => { const [isEditing, setIsEditing] = useState(false); const [content, setContent] = useState(item.content); const [isPending, startTransition] = useTransition(); const styles = categoryStyles[item.category]; async function handleSave() { if (content.trim() === item.content) { setIsEditing(false); return; } if (!content.trim()) { // If empty, delete startTransition(async () => { await deleteSwotItem(item.id, sessionId); }); return; } startTransition(async () => { await updateSwotItem(item.id, sessionId, { content: content.trim() }); setIsEditing(false); }); } async function handleDelete() { startTransition(async () => { await deleteSwotItem(item.id, sessionId); }); } async function handleDuplicate() { startTransition(async () => { await duplicateSwotItem(item.id, sessionId); }); } function handleKeyDown(e: React.KeyboardEvent) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSave(); } else if (e.key === 'Escape') { setContent(item.content); setIsEditing(false); } } function handleClick() { if (linkMode) { onSelect(); } } return (
{isEditing ? (