Files
COS498-HW3/backend/modules/RoutingManager.js
T
2025-11-26 04:08:02 +00:00

152 lines
4.4 KiB
JavaScript

// Helper functions for server-side rendering
function loadBooks(db) {
return new Promise((resolve, reject) => {
const query = 'SELECT id, folder_name, display_name, author FROM books ORDER BY display_name';
db.all(query, [], (err, rows) => {
if (err) {
console.error('Error loading books from database:', err.message);
resolve([]);
} else {
const books = rows.map(row => ({
id: row.id,
name: row.folder_name,
displayName: row.display_name || row.folder_name.replace(/-/g, ' '),
author: row.author
}));
resolve(books);
}
});
});
}
function loadChapters(db, bookName) {
return new Promise((resolve, reject) => {
const query = `
SELECT c.id, c.chapter_number, c.display_name, c.filename, b.folder_name
FROM chapters c
JOIN books b ON c.book_id = b.id
WHERE b.folder_name = ?
ORDER BY c.chapter_number
`;
db.all(query, [bookName], (err, rows) => {
if (err) {
console.error('Error loading chapters from database:', err.message);
resolve([]);
} else {
const chapters = rows.map(row => ({
id: row.id,
chapterNumber: row.chapter_number,
filename: row.filename,
displayName: row.display_name,
url: `/pdf/${row.folder_name}/${encodeURIComponent(row.filename)}`
}));
resolve(chapters);
}
});
});
}
// Page Route handlers
async function homePage(db, req, res) {
try {
const books = await loadBooks(db);
res.render('index', {
title: 'Book Viewer',
books: books,
selectedBook: null,
selectedChapter: null,
chapters: []
});
} catch (error) {
console.error('Error loading books for home page:', error);
res.render('index', {
title: 'Book Viewer',
books: [],
selectedBook: null,
selectedChapter: null,
chapters: [],
error: 'Failed to load books'
});
}
}
async function bookPage(db, req, res) {
const bookName = req.params.bookName;
try {
const [books, chapters] = await Promise.all([
loadBooks(db),
loadChapters(db, bookName)
]);
const selectedBook = books.find(book => book.name === bookName);
if (!selectedBook) {
return res.redirect('/');
}
res.render('index', {
title: 'Book Viewer',
books: books,
selectedBook: selectedBook,
selectedChapter: null,
chapters: chapters
});
} catch (error) {
console.error('Error loading book page:', error);
res.redirect('/');
}
}
async function chapterPage(db, req, res) {
const bookName = req.params.bookName;
const chapterFile = decodeURIComponent(req.params.chapterFile);
try {
const [books, chapters] = await Promise.all([
loadBooks(db),
loadChapters(db, bookName)
]);
const selectedBook = books.find(book => book.name === bookName);
const selectedChapter = chapters.find(chapter => chapter.filename === chapterFile);
if (!selectedBook || !selectedChapter) {
return res.redirect('/');
}
res.render('index', {
title: 'Book Viewer',
books: books,
selectedBook: selectedBook,
selectedChapter: selectedChapter,
chapters: chapters
});
} catch (error) {
console.error('Error loading chapter page:', error);
res.redirect('/');
}
}
// Setup routes function
function setupRoutes(app, db) {
// Page Routes
app.get('/', async (req, res) => {
await homePage(db, req, res);
});
app.get('/book/:bookName', async (req, res) => {
await bookPage(db, req, res);
});
app.get('/book/:bookName/chapter/:chapterFile', async (req, res) => {
await chapterPage(db, req, res);
});
}
module.exports = {
setupRoutes,
loadBooks,
loadChapters,
homePage,
bookPage,
chapterPage
};