Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions library-ui/src/components/libclient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,15 @@ export default function LibClient() {
showDtls = true;
}
if (contentType === 'book_dtls') {
const copies = res.data.copies;
res.data = copies.map((copy: { imprint: string, status: string }) => {
return copy.imprint + ' | ' + copy.status;
const { title, author, bookInstances } = res.data;
// Display book title and author at the top
const headerInfo = [`Title: ${title}`, `Author: ${author}`];
// Map book instances to display format
const instancesInfo = bookInstances.map((instance: { imprint: string, status: string }) => {
return `Copy: ${instance.imprint} | Status: ${instance.status}`;
});
// Combine header and instances information
res.data = [...headerInfo, ...instancesInfo];
}
setContent({ data: res.data, dtls: showDtls });
});
Expand Down
36 changes: 36 additions & 0 deletions models/book.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ export interface IBook extends Document {
* @extends Model
* @property {Function} getAllBooksWithAuthors - A function to get all books with authors.
* @property {Function} getBookCount - A function to get the count of books.
* @property {Function} getBookDetails - A function to get the details of a specific book.
*/
interface IBookModel extends Model<IBook> {
getAllBooksWithAuthors(projectionOpts: string, sortOpts?: { [key: string]: 1 | -1 }): Promise<IBook[]>;
getBookCount(fitler?: FilterQuery<IBook>): Promise<number>;
getBookDetails(bookId: string): Promise<any>;
}

/**
Expand Down Expand Up @@ -83,6 +85,40 @@ BookSchema.statics.getBookCount = async function (filter?: FilterQuery<IBook>):
return this.countDocuments(filter || {});
}

/**
* retrieves the details of a specific book including its author information and book instances
* @param bookId the ID of the book to retrieve details for
* @returns a promise that resolves to the book details or null if not found
*/
BookSchema.statics.getBookDetails = async function(bookId: string): Promise<any> {
try {
const BookInstance = mongoose.model('BookInstance');

// Find book by ID and populate author information
const book = await this.findById(bookId).populate('author');

if (!book) {
return null;
}

// Get all book instances for this book
const bookInstances = await BookInstance.find({ book: bookId });

// Format response with required fields
return {
title: book.title,
author: book.author.name,
bookInstances: bookInstances.map(instance => ({
imprint: instance.imprint,
status: instance.status
}))
};
} catch (error) {
console.error('Error getting book details:', error);
return null;
}
}

/**
* retrieves an existing author by name and an existing genre by name,
* and saves a new book in this collection with the provided title, summary, and ISBN.
Expand Down
33 changes: 33 additions & 0 deletions pages/book_dtls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import express from 'express';
import Book from '../models/book';

const router = express.Router();

/**
* @route GET /book_dtls
* @query id - The ID of the book to retrieve details for
* @returns An object containing the book title, author name, and book instances with imprint and status
* @description Retrieves detailed information about a specific book by its ID
*/
router.get('/', async (req, res) => {
try {
const bookId = req.query.id as string;

if (!bookId) {
return res.status(400).send({ error: 'Book ID is required' });
}

const bookDetails = await Book.getBookDetails(bookId);

if (!bookDetails) {
return res.status(404).send({ error: 'Book not found' });
}

res.status(200).send(bookDetails);
} catch (error) {
console.error('Error in book details route:', error);
res.status(500).send({ error: 'Internal server error' });
}
});

export default router;
3 changes: 3 additions & 0 deletions server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import availableRouter from './pages/books_status';
import bookRouter from './pages/books';
import authorRouter from './pages/authors';
import createBookRouter from './pages/create_book';
import bookDetailsRouter from './pages/book_dtls';

// Create express app
const app = express();
Expand Down Expand Up @@ -45,3 +46,5 @@ app.use('/books', bookRouter);
app.use('/authors', authorRouter);

app.use('/newbook', createBookRouter);

app.use('/book_dtls', bookDetailsRouter);