Implement Google Books API integration for book updates and enhance library management features
- Added a new endpoint in `index.js` to update book data using the Google Books API, allowing for real-time updates based on ISBN. - Introduced a `rebuild_book_entries` function in `libraryManager.py` to facilitate user-driven updates of book entries from the Google Books API. - Enhanced error handling and user prompts for better interaction during book updates. - Updated `public/index.html` and `public/script.js` to improve the user interface and support new functionalities. - Modified styles in `public/styles.css` to enhance the layout and usability of the checkout button and location prompt.
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ramsey Library</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<button id="dark-mode-toggle">🌙</button>
|
||||
<h1>Ramsey Library</h1>
|
||||
@@ -32,7 +34,7 @@
|
||||
// Fetch all books when the page loads
|
||||
window.onload = fetchBooks('');
|
||||
|
||||
document.getElementById('search-bar').addEventListener('input', function() {
|
||||
document.getElementById('search-bar').addEventListener('input', function () {
|
||||
fetchBooks(this.value);
|
||||
});
|
||||
|
||||
@@ -74,60 +76,60 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Utility function to get a cookie by name
|
||||
function getCookie(name) {
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) return parts.pop().split(';').shift();
|
||||
}
|
||||
|
||||
// Utility function to set a cookie
|
||||
function setCookie(name, value, days) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
const expires = `expires=${date.toUTCString()}`;
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/`;
|
||||
}
|
||||
|
||||
// Client-side function to request checkout
|
||||
function requestCheckout(isbn) {
|
||||
let email = getCookie('lastEmail') || '';
|
||||
let name = getCookie('lastName') || '';
|
||||
|
||||
// Prompt the user for email and name, pre-filling with existing values if available
|
||||
email = prompt('Please enter your email:', email);
|
||||
name = prompt('Please enter your name:', name);
|
||||
|
||||
if (!email || !name) {
|
||||
alert('Email and name are required to proceed with checkout.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the email and name in cookies for future use
|
||||
setCookie('lastEmail', email, 7); // Store for 7 days
|
||||
setCookie('lastName', name, 7); // Store for 7 days
|
||||
|
||||
fetch(`/api/checkout/${isbn}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ email, name })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Checkout request sent successfully.');
|
||||
} else {
|
||||
alert(data.error || 'Failed to send checkout request.');
|
||||
// Utility function to get a cookie by name
|
||||
function getCookie(name) {
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) return parts.pop().split(';').shift();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('An error occurred while sending the checkout request.');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Utility function to set a cookie
|
||||
function setCookie(name, value, days) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
const expires = `expires=${date.toUTCString()}`;
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/`;
|
||||
}
|
||||
|
||||
// Client-side function to request checkout
|
||||
function requestCheckout(isbn) {
|
||||
let email = getCookie('lastEmail') || '';
|
||||
let name = getCookie('lastName') || '';
|
||||
|
||||
// Prompt the user for email and name, pre-filling with existing values if available
|
||||
email = prompt('Please enter your email:', email);
|
||||
name = prompt('Please enter your name:', name);
|
||||
|
||||
if (!email || !name) {
|
||||
alert('Email and name are required to proceed with checkout.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the email and name in cookies for future use
|
||||
setCookie('lastEmail', email, 7); // Store for 7 days
|
||||
setCookie('lastName', name, 7); // Store for 7 days
|
||||
|
||||
fetch(`/api/checkout/${isbn}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ email, name })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Checkout request sent successfully.');
|
||||
} else {
|
||||
alert(data.error || 'Failed to send checkout request.');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('An error occurred while sending the checkout request.');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function sortTable(columnIndex) {
|
||||
const table = document.getElementById('book-table');
|
||||
@@ -171,4 +173,5 @@ function requestCheckout(isbn) {
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
@@ -259,7 +259,8 @@ function requestCheckout(isbn) {
|
||||
fetch(`/api/checkout/${isbn}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Basic ' + btoa(username + ':' + password)
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
|
||||
@@ -197,4 +197,49 @@ body.dark-mode #book-table-body tr:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
/* Center the checkout button and make it fill the cell */
|
||||
#book-table td button {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box; /* Ensure padding and border are included in the element's total width and height */
|
||||
}
|
||||
|
||||
/* Add more styles as needed for other elements */
|
||||
|
||||
#location-prompt {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
padding: 20px;
|
||||
border: 2px solid #000;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#location-prompt label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#location-prompt input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#location-prompt select {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#location-prompt button {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user