/* * ReferenceLayout.tsx * Purpose: Implements one of the generic fallback slide layouts used when a template-specific renderer is unavailable. * Used by: components/slides/SlideFactory. * Depends on: Template styling props and inline field-edit callbacks. */ 'use client'; import React, { useState } from 'react'; import { TemplateStyles } from '@/data/templates'; export interface ReferenceLayoutProps { title: string; items: Array<{ text: string }>; styles: TemplateStyles; slideId?: string; isEditable?: boolean; onFieldUpdate?: (slideId: string, field: string, value: string, index?: number) => void; } export default function ReferenceLayout({ title, items, styles, slideId, isEditable = false, onFieldUpdate, }: ReferenceLayoutProps) { const [editingField, setEditingField] = useState<{ field: string; index?: number } | null>(null); const [tempTitle, setTempTitle] = useState(title); const [tempItems, setTempItems] = useState(items.map((i) => i.text)); const handleBlur = (field: string, index?: number) => { if (!slideId || !onFieldUpdate) return; if (field === 'title' && tempTitle !== title) onFieldUpdate(slideId, 'title', tempTitle); if (field === 'items' && index !== undefined && tempItems[index] !== items[index]?.text) onFieldUpdate(slideId, 'items', tempItems[index], index); setEditingField(null); }; const handleKeyDown = (e: React.KeyboardEvent, field: string, index?: number) => { if (e.key === 'Enter') { e.preventDefault(); handleBlur(field, index); } if (e.key === 'Escape') { setEditingField(null); setTempTitle(title); setTempItems(items.map((i) => i.text)); } }; return (
{styles.dotPattern && (
)}
{/* Title */} {editingField?.field === 'title' ? ( setTempTitle(e.target.value)} onBlur={() => handleBlur('title')} onKeyDown={(e) => handleKeyDown(e, 'title')} className="bg-transparent outline-none mb-8" style={{ fontFamily: styles.fonts.heading, fontSize: '40px', fontWeight: 'bold', textTransform: 'uppercase', backgroundColor: styles.colors.accent, border: `${styles.border.width} solid ${styles.colors.border}`, boxShadow: styles.border.shadow, padding: '8px 24px', color: styles.colors.text, }} autoFocus /> ) : (

{ if (isEditable) { setEditingField({ field: 'title' }); setTempTitle(title); } }} > {title}

)} {/* Reference Items */}
{items.map((item, i) => (
[{i + 1}] {editingField?.field === 'items' && editingField?.index === i ? ( { const next = [...tempItems]; next[i] = e.target.value; setTempItems(next); }} onBlur={() => handleBlur('items', i)} onKeyDown={(e) => handleKeyDown(e, 'items', i)} className="flex-1 bg-transparent outline-none" style={{ fontFamily: styles.fonts.body, fontSize: '16px', color: styles.colors.text }} autoFocus /> ) : ( { if (isEditable) { setEditingField({ field: 'items', index: i }); setTempItems(items.map((x) => x.text)); } }} > {item.text} )}
))}
); }