diff --git a/teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/FieldPlacer.tsx b/teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/FieldPlacer.tsx index 87c0fed..96c8a21 100644 --- a/teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/FieldPlacer.tsx +++ b/teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/FieldPlacer.tsx @@ -12,6 +12,7 @@ import { type DragEndEvent, } from '@dnd-kit/core'; import { CSS } from '@dnd-kit/utilities'; +import { getFieldType, type SignatureFieldType } from '@/lib/db/schema'; import type { SignatureFieldData } from '@/lib/db/schema'; interface PageInfo { @@ -65,18 +66,27 @@ async function persistFields(docId: string, fields: SignatureFieldData[]) { } } +// Token color palette — each maps to a SignatureFieldType +const PALETTE_TOKENS: Array<{ id: SignatureFieldType; label: string; color: string }> = [ + { id: 'client-signature', label: 'Signature', color: '#2563eb' }, // blue + { id: 'initials', label: 'Initials', color: '#7c3aed' }, // purple + { id: 'checkbox', label: 'Checkbox', color: '#059669' }, // green + { id: 'date', label: 'Date', color: '#d97706' }, // amber + { id: 'text', label: 'Text', color: '#64748b' }, // slate +]; + // Draggable token in the palette -function DraggableToken({ id }: { id: string }) { +function DraggableToken({ id, label, color }: { id: string; label: string; color: string }) { const { attributes, listeners, setNodeRef, isDragging } = useDraggable({ id }); const style: React.CSSProperties = { // No transform — DragOverlay handles the ghost. Applying transform here causes snap-back animation. opacity: isDragging ? 0.4 : 1, cursor: 'grab', padding: '6px 12px', - border: '2px dashed #2563eb', + border: `2px dashed ${color}`, borderRadius: '4px', - background: 'rgba(37,99,235,0.08)', - color: '#2563eb', + background: `${color}14`, // ~8% opacity tint + color, fontSize: '13px', fontWeight: 600, userSelect: 'none', @@ -85,7 +95,7 @@ function DraggableToken({ id }: { id: string }) { return (
- + Signature Field + + {label}
); } @@ -147,7 +157,7 @@ interface FieldPlacerProps { export function FieldPlacer({ docId, pageInfo, currentPage, children, readOnly = false }: FieldPlacerProps) { const [fields, setFields] = useState([]); - const [isDraggingToken, setIsDraggingToken] = useState(false); + const [isDraggingToken, setIsDraggingToken] = useState(null); const containerRef = useRef(null); // Track rendered canvas dimensions in state so renderFields re-runs when they change const [containerSize, setContainerSize] = useState<{ w: number; h: number } | null>(null); @@ -218,7 +228,7 @@ export function FieldPlacer({ docId, pageInfo, currentPage, children, readOnly = const handleDragEnd = useCallback( (event: DragEndEvent) => { - setIsDraggingToken(false); + setIsDraggingToken(null); if (readOnly) return; @@ -661,7 +671,7 @@ export function FieldPlacer({ docId, pageInfo, currentPage, children, readOnly = return ( setIsDraggingToken(true)} + onDragStart={(event) => setIsDraggingToken(event.active.id as string)} onDragEnd={handleDragEnd} > {/* Palette — hidden in read-only mode */} @@ -679,7 +689,9 @@ export function FieldPlacer({ docId, pageInfo, currentPage, children, readOnly = }} > Field Palette: - + {PALETTE_TOKENS.map((token) => ( + + ))} )} @@ -696,26 +708,30 @@ export function FieldPlacer({ docId, pageInfo, currentPage, children, readOnly = {/* Ghost overlay during drag */} - {isDraggingToken ? ( -
{ + const tokenMeta = PALETTE_TOKENS.find((t) => t.id === isDraggingToken); + const label = tokenMeta?.label ?? 'Field'; + const color = tokenMeta?.color ?? '#2563eb'; + const isCheckbox = isDraggingToken === 'checkbox'; + return ( +
- Signature -
- ) : null} + }}> + {!isCheckbox && label} +
+ ); + })() : null}
);