Files
Umbra-Bookshelf/bd-bookshelf-plugin/admin/js/bd-bookshelf-admin.js
bdm 38cdebd0c6 Track Bookshelf WordPress theme, plugins and specs
Initial import of the bdmurphy Bookshelf work: the bd-bookshelf theme,
bd-bookshelf-plugin, bd-bookshelfhelper and bd-simpleemail plugins, plus
the specification documents, mockups and release archives.
2026-09-28 06:24:25 -07:00

847 lines
30 KiB
JavaScript

/**
* BD Bookshelf - Admin JavaScript
*
* @package BD_Bookshelf
*/
(function($) {
'use strict';
$(document).ready(function() {
// Initialize media uploader for book cover
initCoverUploader();
// Initialize media uploader for author photo
initAuthorPhotoUploader();
// Book form
$('#bd-bookshelf-book-form').on('submit', function(e) {
e.preventDefault();
saveBook();
});
// Delete book
$(document).on('click', '.bd-bookshelf-delete', function(e) {
e.preventDefault();
var bookId = $(this).data('id');
if (confirm('Are you sure you want to delete this book?')) {
deleteBook(bookId);
}
});
// Author Modal
initAuthorModal();
// Series Modal
initSeriesModal();
// Shortcode Modal
initShortcodeModal();
// Sites form
$('#bd-bookshelf-sites-form').on('submit', function(e) {
e.preventDefault();
saveSites();
});
// Settings form
$('#bd-bookshelf-settings-form').on('submit', function(e) {
e.preventDefault();
saveSettings();
});
// Import CSV form
$('#bd-bookshelf-import-csv-form').on('submit', function(e) {
e.preventDefault();
importCSV();
});
// Import Posts form
$('#bd-bookshelf-import-posts-form').on('submit', function(e) {
e.preventDefault();
importPosts();
});
// Manual sync
$('#bd-bookshelf-manual-sync').on('click', function() {
var btn = $(this);
btn.prop('disabled', true).text('Syncing...');
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_sync_ratings',
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
alert(response.data.message);
location.reload();
} else {
alert('Error: ' + response.data.message);
}
},
complete: function() {
btn.prop('disabled', false).text('Sync Now');
}
});
});
// Regenerate retail links
$('#bd-bookshelf-regenerate-links').on('click', function() {
var btn = $(this);
var bookId = btn.data('book-id');
btn.prop('disabled', true).text('Regenerating...');
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_regenerate_links',
book_id: bookId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
$('#bd-bookshelf-retail-links').html(response.data.html);
alert('Retail links regenerated!');
} else {
alert('Error: ' + response.data.message);
}
},
complete: function() {
btn.prop('disabled', false).text('Regenerate Links');
}
});
});
// Scan forms
initScanForms();
});
/**
* Initialize Scan Forms
*/
function initScanForms() {
// Goodreads scan
$('#bd-bookshelf-goodreads-scan-form').on('submit', function(e) {
e.preventDefault();
var authorId = $('#goodreads_author_id').val();
if (!authorId) {
alert('Please enter a Goodreads Author ID');
return;
}
scanAuthor('goodreads', authorId);
});
// Amazon scan
$('#bd-bookshelf-amazon-scan-form').on('submit', function(e) {
e.preventDefault();
var authorId = $('#amazon_author_id').val();
if (!authorId) {
alert('Please enter an Amazon Author ID');
return;
}
scanAuthor('amazon', authorId);
});
// Select all books
$(document).on('change', '#select-all-books', function() {
$('.book-checkbox').prop('checked', $(this).prop('checked'));
});
// Import selected books
$('#bd-bookshelf-import-selected').on('click', function() {
importSelectedBooks();
});
}
/**
* Scan author from source
*/
function scanAuthor(source, authorId) {
var action = source === 'goodreads' ? 'bd_bookshelf_scan_goodreads' : 'bd_bookshelf_scan_amazon';
$('#bd-bookshelf-scan-results').hide();
$('body').css('cursor', 'wait');
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: action,
author_id: authorId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
$('body').css('cursor', 'default');
if (response.success) {
displayScanResults(response.data);
} else {
alert('Error: ' + response.data.message);
}
},
error: function() {
$('body').css('cursor', 'default');
alert('An error occurred while scanning. Please try again.');
}
});
}
/**
* Display scan results
*/
function displayScanResults(data) {
var author = data.author;
var books = data.books;
var source = data.source;
// Show results section
$('#bd-bookshelf-scan-results').show();
// Display author info
var authorHtml = '<div class="bd-bookshelf-author-card">';
if (author.photo) {
authorHtml += '<img src="' + author.photo + '" style="width:100px;height:100px;border-radius:50%;margin-right:20px;float:left">';
}
authorHtml += '<h3>' + (author.name || 'Unknown Author') + '</h3>';
if (author.bio) {
authorHtml += '<p>' + author.bio.substring(0, 200) + '...</p>';
}
authorHtml += '<p><strong>Source:</strong> ' + source.charAt(0).toUpperCase() + source.slice(1) + '</p>';
authorHtml += '<p><strong>Books Found:</strong> ' + books.length + '</p>';
authorHtml += '<div style="clear:both"></div></div>';
$('#bd-bookshelf-author-info').html(authorHtml);
// Display books
var booksHtml = '';
books.forEach(function(book, index) {
booksHtml += '<tr>';
booksHtml += '<td><input type="checkbox" class="book-checkbox" value="' + index + '" checked></td>';
booksHtml += '<td>';
if (book.cover_image) {
booksHtml += '<img src="' + book.cover_image + '" style="width:60px;height:auto">';
}
booksHtml += '</td>';
booksHtml += '<td>' + (book.title || '') + '</td>';
booksHtml += '<td>' + (book.isbn || book.isbn13 || book.asin || '') + '</td>';
booksHtml += '<td>' + (book.rating || '0') + '/5</td>';
booksHtml += '<td>' + (book.published || '') + '</td>';
booksHtml += '<td>' + (book.description ? book.description.substring(0, 100) + '...' : '') + '</td>';
booksHtml += '</tr>';
// Store book data in hidden fields
booksHtml += '<input type="hidden" name="book_data[' + index + '][title]" value="' + (book.title || '').replace(/"/g, '&quot;') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][isbn]" value="' + (book.isbn || '') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][isbn13]" value="' + (book.isbn13 || '') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][cover_image]" value="' + (book.cover_image || '') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][rating]" value="' + (book.rating || '0') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][published]" value="' + (book.published || '') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][description]" value="' + (book.description || '').replace(/"/g, '&quot;') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][goodreads_id]" value="' + (book.goodreads_id || '') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][asin]" value="' + (book.asin || '') + '">';
booksHtml += '<input type="hidden" name="book_data[' + index + '][format]" value="' + (book.format || '') + '">';
});
$('#bd-bookshelf-books-list').html(booksHtml);
// Store author data
$('#bd-bookshelf-scan-results').data('author', author);
$('#bd-bookshelf-scan-results').data('source', source);
// Scroll to results
$('html, body').animate({
scrollTop: $('#bd-bookshelf-scan-results').offset().top
}, 500);
}
/**
* Import selected books
*/
function importSelectedBooks() {
var books = [];
var author = $('#bd-bookshelf-scan-results').data('author');
var source = $('#bd-bookshelf-scan-results').data('source');
$('.book-checkbox:checked').each(function() {
var index = $(this).val();
var bookData = {
title: $('input[name="book_data[' + index + '][title]"]').val(),
isbn: $('input[name="book_data[' + index + '][isbn]"]').val(),
isbn13: $('input[name="book_data[' + index + '][isbn13]"]').val(),
cover_image: $('input[name="book_data[' + index + '][cover_image]"]').val(),
rating: $('input[name="book_data[' + index + '][rating]"]').val(),
published: $('input[name="book_data[' + index + '][published]"]').val(),
description: $('input[name="book_data[' + index + '][description]"]').val(),
goodreads_id: $('input[name="book_data[' + index + '][goodreads_id]"]').val(),
asin: $('input[name="book_data[' + index + '][asin]"]').val() || '',
format: $('input[name="book_data[' + index + '][format]"]').val() || '',
};
books.push(bookData);
});
if (books.length === 0) {
alert('Please select at least one book to import');
return;
}
if (!confirm('Import ' + books.length + ' book(s)?')) {
return;
}
$('body').css('cursor', 'wait');
// Build form data manually for proper nested array handling
var formData = new FormData();
formData.append('action', 'bd_bookshelf_import_scraped');
formData.append('nonce', bdBookshelfAdmin.nonce);
formData.append('source', source);
// Add author data
if (author) {
formData.append('author[name]', author.name || '');
formData.append('author[bio]', author.bio || '');
formData.append('author[photo]', author.photo || '');
formData.append('author[id]', author.id || '');
}
// Add books array
books.forEach(function(book, i) {
formData.append('books[' + i + '][title]', book.title || '');
formData.append('books[' + i + '][isbn]', book.isbn || '');
formData.append('books[' + i + '][isbn13]', book.isbn13 || '');
formData.append('books[' + i + '][cover_image]', book.cover_image || '');
formData.append('books[' + i + '][rating]', book.rating || '0');
formData.append('books[' + i + '][published]', book.published || '');
formData.append('books[' + i + '][description]', book.description || '');
formData.append('books[' + i + '][goodreads_id]', book.goodreads_id || '');
formData.append('books[' + i + '][asin]', book.asin || '');
formData.append('books[' + i + '][format]', book.format || '');
});
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
$('body').css('cursor', 'default');
if (response.success) {
alert(response.data.message);
if (response.data.imported > 0 || response.data.updated > 0) {
location.reload();
}
} else {
alert('Error: ' + response.data.message);
}
},
error: function() {
$('body').css('cursor', 'default');
alert('An error occurred while importing. Please try again.');
}
});
}
/**
* Initialize Cover Image Uploader
*/
function initCoverUploader() {
var coverFrame;
$('#cover-upload-btn').on('click', function(e) {
e.preventDefault();
if (coverFrame) {
coverFrame.open();
return;
}
coverFrame = wp.media({
title: bdBookshelfAdmin.mediaTitle,
button: { text: bdBookshelfAdmin.mediaButton },
multiple: false,
library: { type: 'image' }
});
coverFrame.on('select', function() {
var attachment = coverFrame.state().get('selection').first().toJSON();
var url = attachment.sizes && attachment.sizes.medium ? attachment.sizes.medium.url : attachment.url;
$('#cover_image').val(attachment.url);
$('#cover-preview').html('<img src="' + url + '" style="max-width:200px;height:auto">');
$('#cover-remove-btn').show();
});
coverFrame.open();
});
$('#cover-remove-btn').on('click', function(e) {
e.preventDefault();
$('#cover_image').val('');
$('#cover-preview').html('');
$(this).hide();
});
}
/**
* Initialize Author Photo Uploader
*/
function initAuthorPhotoUploader() {
var photoFrame;
$('#author-photo-btn').on('click', function(e) {
e.preventDefault();
if (photoFrame) {
photoFrame.open();
return;
}
photoFrame = wp.media({
title: 'Select Author Photo',
button: { text: 'Use This Photo' },
multiple: false,
library: { type: 'image' }
});
photoFrame.on('select', function() {
var attachment = photoFrame.state().get('selection').first().toJSON();
var url = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
$('#author_photo_url').val(attachment.url);
$('#author-photo-preview').html('<img src="' + url + '" style="max-width:100px;height:auto">');
$('#author-photo-remove').show();
});
photoFrame.open();
});
$('#author-photo-remove').on('click', function(e) {
e.preventDefault();
$('#author_photo_url').val('');
$('#author-photo-preview').html('');
$(this).hide();
});
}
/**
* Initialize Author Modal
*/
function initAuthorModal() {
// Open modal for new author
$('#bd-bookshelf-add-author').on('click', function() {
$('#author_id').val(0);
$('#author_display_name').val('');
$('#author_email').val('');
$('#author_website').val('');
$('#author_bio').val('');
$('#author_goodreads_id').val('');
$('#author_photo_url').val('');
$('#author-photo-preview').html('');
$('#author-photo-remove').hide();
$('#bd-bookshelf-author-modal-title').text('Add New Author');
$('#bd-bookshelf-author-modal').show();
});
// Edit author
$(document).on('click', '.bd-bookshelf-edit-author', function(e) {
e.preventDefault();
var authorId = $(this).data('id');
// Fetch author data
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_get_author',
id: authorId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
var author = response.data;
$('#author_id').val(author.id);
$('#author_display_name').val(author.display_name);
$('#author_email').val(author.email);
$('#author_website').val(author.website);
$('#author_bio').val(author.bio);
$('#author_goodreads_id').val(author.goodreads_author_id);
$('#author_photo_url').val(author.photo_url);
if (author.photo_url) {
$('#author-photo-preview').html('<img src="' + author.photo_url + '" style="max-width:100px;height:auto">');
$('#author-photo-remove').show();
} else {
$('#author-photo-preview').html('');
$('#author-photo-remove').hide();
}
$('#bd-bookshelf-author-modal-title').text('Edit Author');
$('#bd-bookshelf-author-modal').show();
}
}
});
});
// Delete author
$(document).on('click', '.bd-bookshelf-delete-author', function(e) {
e.preventDefault();
var authorId = $(this).data('id');
if (confirm('Are you sure you want to delete this author?')) {
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_delete_author',
id: authorId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.data.message);
}
}
});
}
});
// Save author
$('#bd-bookshelf-author-form').on('submit', function(e) {
e.preventDefault();
var data = $(this).serialize();
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: data + '&action=bd_bookshelf_save_author',
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.data.message);
}
}
});
});
// Close modal
$(document).on('click', '.bd-bookshelf-modal-close', function() {
$(this).closest('.bd-bookshelf-modal').hide();
});
}
/**
* Initialize Series Modal
*/
function initSeriesModal() {
// Open modal for new series
$('#bd-bookshelf-add-series').on('click', function() {
$('#series_id_input').val(0);
$('#series_name').val('');
$('#series_description').val('');
$('#bd-bookshelf-series-modal-title').text('Add New Series');
$('#bd-bookshelf-series-modal').show();
});
// Edit series
$(document).on('click', '.bd-bookshelf-edit-series', function(e) {
e.preventDefault();
var seriesId = $(this).data('id');
// Fetch series data
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_get_series',
id: seriesId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
var series = response.data;
$('#series_id_input').val(series.id);
$('#series_name').val(series.name);
$('#series_description').val(series.description);
$('#bd-bookshelf-series-modal-title').text('Edit Series');
$('#bd-bookshelf-series-modal').show();
}
}
});
});
// Delete series
$(document).on('click', '.bd-bookshelf-delete-series', function(e) {
e.preventDefault();
var seriesId = $(this).data('id');
if (confirm('Are you sure you want to delete this series? Books in this series will be unlinked.')) {
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_delete_series',
id: seriesId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.data.message);
}
}
});
}
});
// Save series
$('#bd-bookshelf-series-form').on('submit', function(e) {
e.preventDefault();
var data = $(this).serialize();
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: data + '&action=bd_bookshelf_save_series',
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.data.message);
}
}
});
});
}
/**
* Initialize Shortcode Modal
*/
function initShortcodeModal() {
// Open modal for new shortcode
$('#bd-bookshelf-add-shortcode').on('click', function() {
$('#shortcode_id').val(0);
$('#shortcode_slug').val('');
$('#shortcode_target').val('');
$('#shortcode_redirect').val('301');
$('#shortcode_description').val('');
$('#shortcode_slug').prop('readonly', false);
$('#bd-bookshelf-shortcode-modal-title').text('Add New Shortcode');
$('#bd-bookshelf-shortcode-modal').show();
});
// Edit shortcode
$(document).on('click', '.bd-bookshelf-edit-shortcode', function(e) {
e.preventDefault();
var shortcodeId = $(this).data('id');
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_get_shortcode',
id: shortcodeId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
var sc = response.data;
$('#shortcode_id').val(sc.id);
$('#shortcode_slug').val(sc.slug).prop('readonly', true);
$('#shortcode_target').val(sc.target_url);
$('#shortcode_redirect').val(sc.redirect_type);
$('#shortcode_description').val(sc.description);
$('#bd-bookshelf-shortcode-modal-title').text('Edit Shortcode');
$('#bd-bookshelf-shortcode-modal').show();
}
}
});
});
// Delete shortcode
$(document).on('click', '.bd-bookshelf-delete-shortcode', function(e) {
e.preventDefault();
var shortcodeId = $(this).data('id');
if (confirm('Are you sure you want to delete this shortcode?')) {
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_delete_shortcode',
id: shortcodeId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.data.message);
}
}
});
}
});
// Save shortcode
$('#bd-bookshelf-shortcode-form').on('submit', function(e) {
e.preventDefault();
var data = $(this).serialize();
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: data + '&action=bd_bookshelf_save_shortcode',
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.data.message);
}
}
});
});
}
/**
* Save Book
*/
function saveBook() {
var form = $('#bd-bookshelf-book-form');
var data = form.serialize();
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: data + '&action=bd_bookshelf_save_book',
success: function(response) {
if (response.success) {
alert('Book saved!');
if (!form.find('input[name="book_id"]').val() || form.find('input[name="book_id"]').val() === '0') {
window.location.href = window.location.href.split('&book_id=')[0] + '&book_id=' + response.data.id;
}
} else {
alert('Error: ' + response.data.message);
}
}
});
}
/**
* Delete Book
*/
function deleteBook(bookId) {
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: {
action: 'bd_bookshelf_delete_book',
id: bookId,
nonce: bdBookshelfAdmin.nonce
},
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.data.message);
}
}
});
}
/**
* Save Sites/Affiliate Codes
*/
function saveSites() {
var form = $('#bd-bookshelf-sites-form');
var data = form.serialize();
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: data + '&action=bd_bookshelf_save_sites',
success: function(response) {
if (response.success) {
alert('Affiliate codes saved!');
} else {
alert('Error: ' + response.data.message);
}
}
});
}
/**
* Save Settings
*/
function saveSettings() {
var form = $('#bd-bookshelf-settings-form');
var data = form.serialize();
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: data + '&action=bd_bookshelf_save_settings',
success: function(response) {
if (response.success) {
alert('Settings saved!');
} else {
alert('Error: ' + response.data.message);
}
}
});
}
/**
* Import CSV
*/
function importCSV() {
var form = $('#bd-bookshelf-import-csv-form');
var formData = new FormData(form[0]);
formData.append('action', 'bd_bookshelf_import_csv');
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
if (response.success) {
$('#bd-bookshelf-import-results').show();
$('#bd-bookshelf-import-message').text(response.data.message);
} else {
alert('Error: ' + response.data.message);
}
}
});
}
/**
* Import Posts
*/
function importPosts() {
var form = $('#bd-bookshelf-import-posts-form');
var data = form.serialize();
$.ajax({
url: bdBookshelfAdmin.ajaxurl,
type: 'POST',
data: data + '&action=bd_bookshelf_import_posts',
success: function(response) {
if (response.success) {
alert(response.data.message);
} else {
alert('Error: ' + response.data.message);
}
}
});
}
})(jQuery);