# Cross-References Panel - Implementation Plan ## 📋 Overview Implement a comprehensive cross-reference system that helps users discover related Scripture passages, understand context, trace themes, and build a deeper knowledge of interconnected Bible teachings. **Status:** Planning Phase **Priority:** 🔴 High **Estimated Time:** 2 weeks (80 hours) **Target Completion:** TBD --- ## 🎯 Goals & Objectives ### Primary Goals 1. Display relevant cross-references for any verse 2. Provide context and categorization for references 3. Enable quick navigation between related passages 4. Support custom user-added cross-references 5. Visualize reference networks and themes ### User Value Proposition - **For Bible students**: Understand context and connections - **For teachers**: Prepare comprehensive lessons - **For scholars**: Research thematic progressions - **For new readers**: Discover related teachings - **For memorizers**: Build mental maps of Scripture --- ## ✨ Feature Specifications ### 1. Cross-Reference Data Model ```typescript interface CrossReference { id: string fromVerse: VerseReference toVerse: VerseReference type: ReferenceType category: string strength: number // 0-100, relevance score direction: 'forward' | 'backward' | 'bidirectional' source: 'openbible' | 'user' | 'treasury' | 'commentaries' description?: string addedBy?: string // User ID for custom references votes?: number // Community voting on quality createdAt: Date } interface VerseReference { book: string chapter: number verse: number endVerse?: number // For ranges } type ReferenceType = | 'quotation' // Direct quote (OT → NT) | 'allusion' // Indirect reference | 'parallel' // Parallel account (Gospels, Kings/Chronicles) | 'thematic' // Same theme/topic | 'fulfillment' // Prophecy fulfillment | 'contrast' // Contrasting teaching | 'expansion' // Elaboration/explanation | 'application' // Practical application | 'historical' // Historical context | 'wordStudy' // Same Hebrew/Greek word ``` ### 2. Cross-Reference Categories ```typescript const REFERENCE_CATEGORIES = { // Structural 'parallel-passages': 'Parallel Passages', 'quotations': 'Quotations', 'allusions': 'Allusions', // Thematic 'salvation': 'Salvation', 'faith': 'Faith', 'love': 'Love', 'judgment': 'Judgment', 'prophecy': 'Prophecy', 'miracles': 'Miracles', 'parables': 'Parables', 'promises': 'Promises', 'commands': 'Commands', 'covenants': 'Covenants', // Character Studies 'christ-prefigured': 'Christ Prefigured', 'messianic': 'Messianic References', 'holy-spirit': 'Holy Spirit', // Literary 'poetry': 'Poetic Parallels', 'wisdom': 'Wisdom Literature', 'apocalyptic': 'Apocalyptic Literature', // Historical 'chronological': 'Chronological Sequence', 'geographical': 'Same Location', // Custom 'user-defined': 'User Added' } ``` ### 3. UI Layout Options ``` Desktop - Sidebar (Default): ┌────────────────────────────┬──────────────────┐ │ Genesis 1:1-31 │ Cross-References │ │ │ │ │ 1 In the beginning God │ ▸ Quotations (3) │ │ created the heaven and │ • John 1:1-3 │ │ the earth. │ • Heb 11:3 │ │ │ • Rev 4:11 │ │ 2 And the earth was │ │ │ without form... │ ▸ Parallel (2) │ │ │ • Ps 33:6 │ │ │ • Col 1:16 │ │ │ │ │ [verse 3 selected] │ ▸ Thematic (12) │ │ 3 And God said, Let │ • Gen 2:3 │ │ there be light: and │ • 2 Cor 4:6 │ │ there was light. │ • Jas 1:17 │ │ │ + 9 more │ └────────────────────────────┴──────────────────┘ Mobile - Bottom Sheet: ┌─────────────────────────┐ │ Genesis 1:3 │ │ │ │ And God said, Let there │ │ be light: and there was │ │ light. │ │ │ │ [Tap for references] ▲ │ └─────────────────────────┘ ↓ Swipe up ┌─────────────────────────┐ │ ≡ Cross-References (17) │ ├─────────────────────────┤ │ Quotations (3) │ │ • John 1:1-3 → │ │ • Hebrews 11:3 → │ │ │ │ Thematic (12) │ │ • Genesis 2:3 → │ │ • 2 Cor 4:6 → │ │ + 10 more │ └─────────────────────────┘ ``` ### 4. Collapsible Sidebar Component ```typescript interface CrossReferencePanelProps { verse: VerseReference | null position: 'left' | 'right' | 'bottom' defaultOpen: boolean width: number // pixels or percentage } export const CrossReferencePanel: React.FC = ({ verse, position = 'right', defaultOpen = true, width = 320 }) => { const [isOpen, setIsOpen] = useState(defaultOpen) const [references, setReferences] = useState([]) const [loading, setLoading] = useState(false) const [groupBy, setGroupBy] = useState<'type' | 'category'>('type') const [sortBy, setSortBy] = useState<'relevance' | 'book' | 'votes'>('relevance') useEffect(() => { if (!verse) { setReferences([]) return } loadReferences(verse) }, [verse]) const loadReferences = async (verse: VerseReference) => { setLoading(true) try { const response = await fetch( `/api/cross-references?book=${verse.book}&chapter=${verse.chapter}&verse=${verse.verse}` ) const data = await response.json() setReferences(data.references) } catch (error) { console.error('Failed to load cross-references:', error) } finally { setLoading(false) } } const groupedReferences = useMemo(() => { if (groupBy === 'type') { return groupByType(references) } else { return groupByCategory(references) } }, [references, groupBy]) const sortedGroups = useMemo(() => { return Object.entries(groupedReferences).map(([key, refs]) => ({ key, references: sortReferences(refs, sortBy) })) }, [groupedReferences, sortBy]) if (!verse) return null return ( {/* Header */} Cross-References setIsOpen(false)}> {verse.book} {verse.chapter}:{verse.verse} {/* Controls */} Group By Sort By {/* References List */} {loading ? ( ) : references.length === 0 ? ( No cross-references found for this verse. ) : ( sortedGroups.map(group => ( )) )} ) } ``` ### 5. Reference Group Component ```typescript interface ReferenceGroupProps { title: string references: CrossReference[] defaultExpanded?: boolean } const ReferenceGroup: React.FC = ({ title, references, defaultExpanded = true }) => { const [expanded, setExpanded] = useState(defaultExpanded) const [previewVerse, setPreviewVerse] = useState(null) return ( setExpanded(!expanded)} sx={{ display: 'flex', alignItems: 'center', cursor: 'pointer', p: 1, borderRadius: 1, '&:hover': { bgcolor: 'action.hover' } }} > {expanded ? : } {title} ({references.length}) {references.map(ref => ( ))} {/* Preview popover */} {previewVerse && ( setPreviewVerse(null)} /> )} ) } ``` ### 6. Reference Item with Preview ```typescript interface ReferenceItemProps { reference: CrossReference onHover: (verseText: string | null) => void } const ReferenceItem: React.FC = ({ reference, onHover }) => { const router = useRouter() const [verseText, setVerseText] = useState(null) const [loading, setLoading] = useState(false) const handleMouseEnter = async () => { if (verseText) { onHover(verseText) return } setLoading(true) try { const response = await fetch( `/api/bible/verses?` + `book=${reference.toVerse.book}&` + `chapter=${reference.toVerse.chapter}&` + `verse=${reference.toVerse.verse}` ) const data = await response.json() const text = data.verses[0]?.text || '' setVerseText(text) onHover(text) } catch (error) { console.error('Failed to load verse preview:', error) } finally { setLoading(false) } } const handleClick = () => { const { book, chapter, verse } = reference.toVerse router.push(`/bible/${book.toLowerCase()}/${chapter}#verse-${verse}`) } const formatReference = (ref: VerseReference): string => { const baseRef = `${ref.book} ${ref.chapter}:${ref.verse}` return ref.endVerse ? `${baseRef}-${ref.endVerse}` : baseRef } const getTypeIcon = (type: ReferenceType) => { const icons = { quotation: , parallel: , thematic: , fulfillment: , allusion: , // ... more mappings } return icons[type] || } return ( onHover(null)} sx={{ borderRadius: 1, mb: 0.5, '&:hover': { bgcolor: 'action.hover' } }} > {getTypeIcon(reference.type)} {formatReference(reference.toVerse)} {reference.strength >= 80 && ( )} } secondary={reference.description} /> ) } ``` ### 7. Visual Indicators in Text ```typescript // Add superscript indicators in verse text const VerseWithReferences: React.FC<{ verse: BibleVerse references: CrossReference[] }> = ({ verse, references }) => { const hasReferences = references.length > 0 return ( {verse.verseNum} {verse.text} {hasReferences && ( )} ) } ``` ### 8. Add Custom Cross-Reference ```typescript interface AddReferenceDialogProps { open: boolean onClose: () => void fromVerse: VerseReference } const AddReferenceDialog: React.FC = ({ open, onClose, fromVerse }) => { const [toVerse, setToVerse] = useState(null) const [type, setType] = useState('thematic') const [category, setCategory] = useState('') const [description, setDescription] = useState('') const handleSubmit = async () => { if (!toVerse) return try { await fetch('/api/cross-references', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ fromVerse, toVerse, type, category, description, source: 'user' }) }) onClose() } catch (error) { console.error('Failed to add cross-reference:', error) } } return ( Add Cross-Reference From: {fromVerse.book} {fromVerse.chapter}:{fromVerse.verse} Type setCategory(e.target.value)} fullWidth /> setDescription(e.target.value)} multiline rows={3} fullWidth /> ) } ``` ### 9. Bidirectional Linking ```typescript // Automatically create reverse references const createBidirectionalReference = async ( fromVerse: VerseReference, toVerse: VerseReference, type: ReferenceType ) => { // Create forward reference await createReference({ fromVerse, toVerse, type, direction: 'forward' }) // Create backward reference automatically await createReference({ fromVerse: toVerse, toVerse: fromVerse, type, direction: 'backward' }) } ``` ### 10. Search Cross-References ```typescript interface ReferenceSearchProps { onSelect: (reference: CrossReference) => void } const ReferenceSearch: React.FC = ({ onSelect }) => { const [query, setQuery] = useState('') const [results, setResults] = useState([]) const handleSearch = useDebounce(async (searchQuery: string) => { if (searchQuery.length < 3) { setResults([]) return } const response = await fetch( `/api/cross-references/search?q=${encodeURIComponent(searchQuery)}` ) const data = await response.json() setResults(data.references) }, 300) return ( { setQuery(e.target.value) handleSearch(e.target.value) }} fullWidth InputProps={{ startAdornment: }} /> {results.map(ref => ( onSelect(ref)} > ))} ) } ``` --- ## 🗄️ Database Schema ```prisma model CrossReference { id String @id @default(cuid()) // From verse fromBook String fromChapter Int fromVerse Int fromEndVerse Int? // To verse toBook String toChapter Int toVerse Int toEndVerse Int? // Metadata type String // ReferenceType enum category String? strength Int @default(50) // 0-100 direction String @default("bidirectional") source String @default("openbible") // openbible, user, treasury description String? // User tracking (for custom references) addedBy String? userId String? user User? @relation(fields: [userId], references: [id]) // Community features votes Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([fromBook, fromChapter, fromVerse]) @@index([toBook, toChapter, toVerse]) @@index([type, category]) @@index([userId]) } model ReferenceVote { id String @id @default(cuid()) referenceId String userId String value Int // +1 or -1 reference CrossReference @relation(fields: [referenceId], references: [id]) user User @relation(fields: [userId], references: [id]) @@unique([referenceId, userId]) @@index([referenceId]) } ``` --- ## 📊 API Endpoints ```typescript // Get cross-references for a verse GET /api/cross-references Query params: - book: string - chapter: number - verse: number - type?: ReferenceType[] - category?: string[] - minStrength?: number (0-100) Response: { references: CrossReference[] count: number } // Add custom cross-reference POST /api/cross-references Body: { fromVerse: VerseReference toVerse: VerseReference type: ReferenceType category?: string description?: string } Response: { success: boolean reference: CrossReference } // Vote on reference quality POST /api/cross-references/:id/vote Body: { value: 1 | -1 } // Search cross-references GET /api/cross-references/search Query: q=keyword Response: { references: CrossReference[] } // Bulk import cross-references (admin) POST /api/admin/cross-references/import Body: { references: CrossReference[], source: string } ``` --- ## 📅 Implementation Timeline ### Week 1: Foundation & Data **Day 1-2: Database & Data Import** - [ ] Create database schema - [ ] Import OpenBible.info dataset (~65,000 references) - [ ] Build API endpoints - [ ] Test data queries **Day 3-4: UI Components** - [ ] Create sidebar component - [ ] Build reference list UI - [ ] Implement grouping/sorting - [ ] Add loading states **Day 5: Navigation & Preview** - [ ] Implement click navigation - [ ] Build hover preview - [ ] Add verse indicators - [ ] Test UX flow **Deliverable:** Working cross-reference viewer ### Week 2: Advanced Features **Day 1-2: Custom References** - [ ] Build add reference dialog - [ ] Implement bidirectional linking - [ ] Add edit/delete functionality - [ ] Test CRUD operations **Day 3-4: Search & Filter** - [ ] Implement search - [ ] Add advanced filters - [ ] Build category browser - [ ] Add sorting options **Day 5: Polish & Mobile** - [ ] Optimize mobile layout - [ ] Performance tuning - [ ] Bug fixes - [ ] Documentation **Deliverable:** Production-ready cross-reference system --- ## 📚 Data Sources ### OpenBible.info Cross-Reference Dataset - **URL**: https://openbible.info/labs/cross-references/ - **Size**: ~340,000 cross-references - **License**: CC BY 4.0 - **Coverage**: Old & New Testament - **Format**: CSV/JSON ### Treasury of Scripture Knowledge - **Coverage**: Extensive OT/NT references - **Public Domain**: Yes - **Quality**: High (curated by scholars) ### User-Generated References - Allow community contributions - Implement voting/quality system - Moderate for accuracy --- ## 🚀 Deployment Plan ### Pre-Launch - [ ] Import cross-reference dataset - [ ] Test with 1000+ verses - [ ] Performance optimization - [ ] Mobile testing - [ ] Accessibility audit ### Rollout 1. **Beta**: 10% users, collect feedback 2. **Staged**: 50% users 3. **Full**: 100% deployment --- **Document Version:** 1.0 **Last Updated:** 2025-10-13 **Owner:** Development Team **Status:** Ready for Implementation