163 lines
4.0 KiB
TypeScript
163 lines
4.0 KiB
TypeScript
'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 = (
|
|
<Box sx={{ p: 2 }}>
|
|
{/* Verse Header */}
|
|
<Box sx={{ mb: 2, display: 'flex', justifyContent: 'space-between', alignItems: 'start' }}>
|
|
<Typography variant="subtitle1" fontWeight={600}>
|
|
Verse {verse.verseNum}
|
|
</Typography>
|
|
<IconButton size="small" onClick={onClose}>
|
|
<Close />
|
|
</IconButton>
|
|
</Box>
|
|
|
|
{/* Verse Text */}
|
|
<Paper sx={{ p: 2, mb: 2, bgcolor: 'grey.100' }} elevation={0}>
|
|
<Typography variant="body2" sx={{ mb: 1, fontStyle: 'italic' }}>
|
|
{verse.text}
|
|
</Typography>
|
|
</Paper>
|
|
|
|
{/* Bookmark Button */}
|
|
<Box sx={{ mb: 2 }}>
|
|
<Button
|
|
startIcon={isBookmarked ? <Bookmark /> : <BookmarkBorder />}
|
|
onClick={onToggleBookmark}
|
|
variant={isBookmarked ? 'contained' : 'outlined'}
|
|
size="small"
|
|
fullWidth={isMobile}
|
|
>
|
|
{isBookmarked ? 'Bookmarked' : 'Bookmark'}
|
|
</Button>
|
|
</Box>
|
|
|
|
{/* Tabs */}
|
|
<Tabs
|
|
value={tabValue}
|
|
onChange={(_, newValue) => setTabValue(newValue)}
|
|
variant={isMobile ? 'fullWidth' : 'standard'}
|
|
sx={{ borderBottom: 1, borderColor: 'divider' }}
|
|
>
|
|
<Tab label="Notes" />
|
|
<Tab label="Highlights" />
|
|
<Tab label="References" />
|
|
</Tabs>
|
|
|
|
{/* Tab Content */}
|
|
<Box sx={{ pt: 2 }}>
|
|
{tabValue === 0 && (
|
|
<Box>
|
|
<TextField
|
|
fullWidth
|
|
multiline
|
|
rows={3}
|
|
placeholder="Add a note..."
|
|
value={noteText}
|
|
onChange={(e) => setNoteText(e.target.value)}
|
|
size="small"
|
|
sx={{ mb: 1 }}
|
|
/>
|
|
<Button
|
|
variant="contained"
|
|
size="small"
|
|
onClick={handleAddNote}
|
|
disabled={!noteText.trim()}
|
|
>
|
|
Save Note
|
|
</Button>
|
|
</Box>
|
|
)}
|
|
|
|
{tabValue === 1 && (
|
|
<Typography variant="body2" color="text.secondary">
|
|
Highlight colors coming soon
|
|
</Typography>
|
|
)}
|
|
|
|
{tabValue === 2 && (
|
|
<Typography variant="body2" color="text.secondary">
|
|
Cross-references coming soon
|
|
</Typography>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
)
|
|
|
|
if (isMobile) {
|
|
return (
|
|
<Box
|
|
sx={{
|
|
position: 'fixed',
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
zIndex: 100,
|
|
maxHeight: '70vh',
|
|
backgroundColor: 'white',
|
|
borderTopLeftRadius: 16,
|
|
borderTopRightRadius: 16,
|
|
boxShadow: '0 -4px 20px rgba(0,0,0,0.1)',
|
|
overflow: 'auto',
|
|
}}
|
|
>
|
|
{PanelContent}
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Paper
|
|
sx={{
|
|
position: 'fixed',
|
|
right: 0,
|
|
top: 0,
|
|
bottom: 0,
|
|
width: 350,
|
|
zIndex: 100,
|
|
borderRadius: 0,
|
|
boxShadow: '-4px 0 20px rgba(0,0,0,0.1)',
|
|
overflow: 'auto',
|
|
backgroundColor: 'white',
|
|
}}
|
|
>
|
|
{PanelContent}
|
|
</Paper>
|
|
)
|
|
}
|