Add dark mode persistence and book name formatting for professional display
This commit is contained in:
@@ -14,7 +14,11 @@ function App() {
|
|||||||
const [selectedBook, setSelectedBook] = useState<string>('');
|
const [selectedBook, setSelectedBook] = useState<string>('');
|
||||||
const [selectedChapter, setSelectedChapter] = useState<string>('');
|
const [selectedChapter, setSelectedChapter] = useState<string>('');
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [darkMode, setDarkMode] = useState(false);
|
const [darkMode, setDarkMode] = useState(() => {
|
||||||
|
// Load dark mode preference from localStorage
|
||||||
|
const saved = localStorage.getItem('darkMode');
|
||||||
|
return saved ? JSON.parse(saved) : false;
|
||||||
|
});
|
||||||
const [error, setError] = useState<string>('');
|
const [error, setError] = useState<string>('');
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
@@ -26,13 +30,21 @@ function App() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Apply dark mode and save preference
|
||||||
if (darkMode) {
|
if (darkMode) {
|
||||||
document.documentElement.classList.add('dark');
|
document.documentElement.classList.add('dark');
|
||||||
} else {
|
} else {
|
||||||
document.documentElement.classList.remove('dark');
|
document.documentElement.classList.remove('dark');
|
||||||
}
|
}
|
||||||
|
localStorage.setItem('darkMode', JSON.stringify(darkMode));
|
||||||
}, [darkMode]);
|
}, [darkMode]);
|
||||||
|
|
||||||
|
// Helper function to format book names for display
|
||||||
|
const formatBookName = (bookName: string): string => {
|
||||||
|
// Remove leading numbers and underscores, replace underscores with spaces
|
||||||
|
return bookName.replace(/^\d+_/, '').replace(/_/g, ' ');
|
||||||
|
};
|
||||||
|
|
||||||
const loadBooks = async () => {
|
const loadBooks = async () => {
|
||||||
try {
|
try {
|
||||||
console.log('Loading books from API...');
|
console.log('Loading books from API...');
|
||||||
@@ -101,7 +113,7 @@ function App() {
|
|||||||
</button>
|
</button>
|
||||||
<ChevronRight className="h-4 w-4" />
|
<ChevronRight className="h-4 w-4" />
|
||||||
<span className="font-medium text-gray-900 dark:text-gray-100">
|
<span className="font-medium text-gray-900 dark:text-gray-100">
|
||||||
{selectedBook}
|
{formatBookName(selectedBook)}
|
||||||
</span>
|
</span>
|
||||||
{selectedChapter && (
|
{selectedChapter && (
|
||||||
<>
|
<>
|
||||||
@@ -140,18 +152,20 @@ function App() {
|
|||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
<main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||||
{!selectedBook ? (
|
{!selectedBook ? (
|
||||||
<BookSelector books={books} onBookSelect={handleBookSelect} />
|
<BookSelector books={books} onBookSelect={handleBookSelect} formatBookName={formatBookName} />
|
||||||
) : !selectedChapter ? (
|
) : !selectedChapter ? (
|
||||||
<ChapterSelector
|
<ChapterSelector
|
||||||
book={selectedBook}
|
book={selectedBook}
|
||||||
onChapterSelect={handleChapterSelect}
|
onChapterSelect={handleChapterSelect}
|
||||||
onBack={handleBackToBooks}
|
onBack={handleBackToBooks}
|
||||||
|
formatBookName={formatBookName}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<BibleReader
|
<BibleReader
|
||||||
book={selectedBook}
|
book={selectedBook}
|
||||||
chapter={selectedChapter}
|
chapter={selectedChapter}
|
||||||
onBack={handleBackToChapters}
|
onBack={handleBackToChapters}
|
||||||
|
formatBookName={formatBookName}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ interface BibleReaderProps {
|
|||||||
book: string;
|
book: string;
|
||||||
chapter: string;
|
chapter: string;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
|
formatBookName: (bookName: string) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BibleReader: React.FC<BibleReaderProps> = ({ book, chapter, onBack }) => {
|
const BibleReader: React.FC<BibleReaderProps> = ({ book, chapter, onBack, formatBookName }) => {
|
||||||
const [content, setContent] = useState<string>('');
|
const [content, setContent] = useState<string>('');
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [fontSize, setFontSize] = useState<'small' | 'medium' | 'large'>('medium');
|
const [fontSize, setFontSize] = useState<'small' | 'medium' | 'large'>('medium');
|
||||||
@@ -136,7 +137,7 @@ const BibleReader: React.FC<BibleReaderProps> = ({ book, chapter, onBack }) => {
|
|||||||
{/* Chapter Title */}
|
{/* Chapter Title */}
|
||||||
<div className="text-center mb-8">
|
<div className="text-center mb-8">
|
||||||
<h1 className="book-title">
|
<h1 className="book-title">
|
||||||
{book} {chapter}
|
{formatBookName(book)} {chapter}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import { BookOpen } from 'lucide-react';
|
|||||||
interface BookSelectorProps {
|
interface BookSelectorProps {
|
||||||
books: string[];
|
books: string[];
|
||||||
onBookSelect: (book: string) => void;
|
onBookSelect: (book: string) => void;
|
||||||
|
formatBookName: (bookName: string) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BookSelector: React.FC<BookSelectorProps> = ({ books, onBookSelect }) => {
|
const BookSelector: React.FC<BookSelectorProps> = ({ books, onBookSelect, formatBookName }) => {
|
||||||
// Group books by testament
|
// Group books by testament
|
||||||
const oldTestament = books.slice(0, 39); // First 39 books
|
const oldTestament = books.slice(0, 39); // First 39 books
|
||||||
const newTestament = books.slice(39); // Remaining books
|
const newTestament = books.slice(39); // Remaining books
|
||||||
@@ -25,7 +26,7 @@ const BookSelector: React.FC<BookSelectorProps> = ({ books, onBookSelect }) => {
|
|||||||
>
|
>
|
||||||
<BookOpen className="mx-auto h-8 w-8 text-blue-600 dark:text-blue-400 mb-2 group-hover:scale-110 transition-transform" />
|
<BookOpen className="mx-auto h-8 w-8 text-blue-600 dark:text-blue-400 mb-2 group-hover:scale-110 transition-transform" />
|
||||||
<span className="text-sm font-medium text-gray-900 dark:text-gray-100 group-hover:text-blue-600 dark:group-hover:text-blue-400">
|
<span className="text-sm font-medium text-gray-900 dark:text-gray-100 group-hover:text-blue-600 dark:group-hover:text-blue-400">
|
||||||
{book}
|
{formatBookName(book)}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ interface ChapterSelectorProps {
|
|||||||
book: string;
|
book: string;
|
||||||
onChapterSelect: (chapter: string) => void;
|
onChapterSelect: (chapter: string) => void;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
|
formatBookName: (bookName: string) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChapterSelector: React.FC<ChapterSelectorProps> = ({ book, onChapterSelect, onBack }) => {
|
const ChapterSelector: React.FC<ChapterSelectorProps> = ({ book, onChapterSelect, onBack, formatBookName }) => {
|
||||||
const [chapters, setChapters] = useState<string[]>([]);
|
const [chapters, setChapters] = useState<string[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ const ChapterSelector: React.FC<ChapterSelectorProps> = ({ book, onChapterSelect
|
|||||||
{/* Book Title */}
|
{/* Book Title */}
|
||||||
<div className="text-center mb-8">
|
<div className="text-center mb-8">
|
||||||
<h1 className="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-2">
|
<h1 className="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-2">
|
||||||
{book}
|
{formatBookName(book)}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-lg text-gray-600 dark:text-gray-400">
|
<p className="text-lg text-gray-600 dark:text-gray-400">
|
||||||
Select a chapter to read
|
Select a chapter to read
|
||||||
|
|||||||
Reference in New Issue
Block a user