From 189240355450ea2d3e5933dac0299d9e093bb71e Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 11 Nov 2025 19:48:13 +0000 Subject: [PATCH] feat: implement VersDetailsPanel with notes, bookmarks, and tabs --- .../components/verse-details-panel.test.tsx | 40 +++++ components/bible/verse-details-panel.tsx | 162 ++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 __tests__/components/verse-details-panel.test.tsx create mode 100644 components/bible/verse-details-panel.tsx diff --git a/__tests__/components/verse-details-panel.test.tsx b/__tests__/components/verse-details-panel.test.tsx new file mode 100644 index 0000000..7199145 --- /dev/null +++ b/__tests__/components/verse-details-panel.test.tsx @@ -0,0 +1,40 @@ +import { render, screen } from '@testing-library/react' +import { VersDetailsPanel } from '@/components/bible/verse-details-panel' + +const mockVerse = { + id: 'v1', + verseNum: 1, + text: 'In the beginning...', + bookId: 1, + chapter: 1 +} + +describe('VersDetailsPanel', () => { + it('renders when open with verse data', () => { + render( + {}} + isBookmarked={false} + onToggleBookmark={() => {}} + onAddNote={() => {}} + /> + ) + expect(screen.getByText(/In the beginning/)).toBeInTheDocument() + }) + + it('does not render when closed', () => { + const { container } = render( + {}} + isBookmarked={false} + onToggleBookmark={() => {}} + onAddNote={() => {}} + /> + ) + expect(container.firstChild).toBeNull() + }) +}) diff --git a/components/bible/verse-details-panel.tsx b/components/bible/verse-details-panel.tsx new file mode 100644 index 0000000..a9d475d --- /dev/null +++ b/components/bible/verse-details-panel.tsx @@ -0,0 +1,162 @@ +'use client' +import { useState } from 'react' +import { Box, Paper, Typography, Tabs, Tab, IconButton, useMediaQuery, useTheme, TextField, Button } from '@mui/material' +import { Close, Bookmark, BookmarkBorder } from '@mui/icons-material' +import { BibleVerse } from '@/types' + +interface VersDetailsPanelProps { + verse: BibleVerse | null + isOpen: boolean + onClose: () => void + isBookmarked: boolean + onToggleBookmark: () => void + onAddNote: (note: string) => void +} + +export function VersDetailsPanel({ + verse, + isOpen, + onClose, + isBookmarked, + onToggleBookmark, + onAddNote, +}: VersDetailsPanelProps) { + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down('sm')) + const [tabValue, setTabValue] = useState(0) + const [noteText, setNoteText] = useState('') + + if (!verse || !isOpen) return null + + const handleAddNote = () => { + if (noteText.trim()) { + onAddNote(noteText) + setNoteText('') + } + } + + const PanelContent = ( + + {/* Verse Header */} + + + Verse {verse.verseNum} + + + + + + + {/* Verse Text */} + + + {verse.text} + + + + {/* Bookmark Button */} + + + + + {/* Tabs */} + setTabValue(newValue)} + variant={isMobile ? 'fullWidth' : 'standard'} + sx={{ borderBottom: 1, borderColor: 'divider' }} + > + + + + + + {/* Tab Content */} + + {tabValue === 0 && ( + + setNoteText(e.target.value)} + size="small" + sx={{ mb: 1 }} + /> + + + )} + + {tabValue === 1 && ( + + Highlight colors coming soon + + )} + + {tabValue === 2 && ( + + Cross-references coming soon + + )} + + + ) + + if (isMobile) { + return ( + + {PanelContent} + + ) + } + + return ( + + {PanelContent} + + ) +}