95 lines
4.1 KiB
HTML
95 lines
4.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Dua's Book Club</title>
|
|
<style>
|
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background-color: #f0f2f5; color: #1c1e21; margin: 0; }
|
|
.container { max-width: 1200px; margin: 30px auto; padding: 20px; }
|
|
h1 { color: #1877f2; text-align: center; font-size: 2.5em; }
|
|
.book-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 25px; }
|
|
.book-card { background: #fff; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); overflow: hidden; text-align: center; transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; }
|
|
.book-card:hover { transform: translateY(-5px); box-shadow: 0 8px 16px rgba(0,0,0,0.1); }
|
|
.book-card img { width: 100%; height: 300px; object-fit: cover; }
|
|
.book-details { padding: 15px; }
|
|
.book-details h2 { font-size: 1.2em; margin: 0 0 15px 0; min-height: 44px; }
|
|
.checkbox-group { display: flex; justify-content: space-around; align-items: center; }
|
|
.checkbox-group label { font-size: 1em; cursor: pointer; display: flex; align-items: center; }
|
|
.checkbox-group input { margin-right: 8px; width: 18px; height: 18px; cursor: pointer; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>Dua's Book Club</h1>
|
|
<div class="book-grid">
|
|
{{range .books}}
|
|
<div class="book-card">
|
|
<img src="{{.ImagePath}}" alt="Cover of {{.Name}}">
|
|
<div class="book-details">
|
|
<h2>{{.Name}}</h2>
|
|
<div class="checkbox-group">
|
|
<label>
|
|
<input type="checkbox" class="read-checkbox" data-book-id="{{.ID}}" data-person="Tuomas" {{if .TuomasRead}}checked{{end}}>
|
|
Tuomas
|
|
</label>
|
|
<label>
|
|
<input type="checkbox" class="read-checkbox" data-book-id="{{.ID}}" data-person="Jenni" {{if .JenniRead}}checked{{end}}>
|
|
Jenni
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// This script sends an update to the server whenever a checkbox is clicked.
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const checkboxes = document.querySelectorAll('.read-checkbox');
|
|
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.addEventListener('change', function() {
|
|
const bookId = this.dataset.bookId;
|
|
const person = this.dataset.person;
|
|
const isRead = this.checked;
|
|
|
|
// Log the data being sent
|
|
console.log(`Updating Book ID: ${bookId}, Person: ${person}, Read: ${isRead}`);
|
|
|
|
// Send the data to the backend API endpoint
|
|
fetch(`/books/${bookId}/update`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
person: person,
|
|
read: isRead,
|
|
}),
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
// If the server response is not OK, throw an error to be caught below
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('Update successful:', data);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error updating status:', error);
|
|
// Revert the checkbox state on failure to reflect the actual server state
|
|
this.checked = !isRead;
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|
|
|