block.json
1 month ago
index.asset.php
1 month ago
index.js
1 month ago
render.php
1 month ago
style-index-rtl.css
1 month ago
style-index.css
1 month ago
view.asset.php
1 month ago
view.js
1 month ago
render.php
659 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Render Book Gallery [Author Pro] Block |
| 4 | */ |
| 5 | |
| 6 | $items_per_page = isset($attributes['itemsPerPage']) ? $attributes['itemsPerPage'] : 12; |
| 7 | $book_page_url = isset($attributes['bookPageUrl']) ? $attributes['bookPageUrl'] : ''; |
| 8 | $show_sidebar = isset($attributes['showSidebar']) ? $attributes['showSidebar'] : true; |
| 9 | |
| 10 | $is_editor = (defined('REST_REQUEST') && REST_REQUEST) || (isset($_REQUEST['context']) && $_REQUEST['context'] === 'edit'); |
| 11 | |
| 12 | // Back Link Logic |
| 13 | $back_link = !empty($book_page_url) ? esc_url($book_page_url) : get_post_type_archive_link('book'); |
| 14 | |
| 15 | // Filter Visibility |
| 16 | $show_search = isset($attributes['showSearch']) ? $attributes['showSearch'] : true; |
| 17 | $show_genre = isset($attributes['showFilterGenre']) ? $attributes['showFilterGenre'] : true; |
| 18 | $show_author = isset($attributes['showFilterAuthor']) ? $attributes['showFilterAuthor'] : true; |
| 19 | $show_series = isset($attributes['showFilterSeries']) ? $attributes['showFilterSeries'] : true; |
| 20 | $show_format = isset($attributes['showFilterFormat']) ? $attributes['showFilterFormat'] : true; |
| 21 | $show_language = isset($attributes['showFilterLanguage']) ? $attributes['showFilterLanguage'] : true; |
| 22 | $show_publisher = isset($attributes['showFilterPublisher']) ? $attributes['showFilterPublisher'] : true; |
| 23 | $show_isbn = isset($attributes['showFilterISBN']) ? $attributes['showFilterISBN'] : true; |
| 24 | $show_price = isset($attributes['showFilterPrice']) ? $attributes['showFilterPrice'] : true; |
| 25 | $show_year = isset($attributes['showFilterYear']) ? $attributes['showFilterYear'] : true; |
| 26 | $show_age = isset($attributes['showFilterAge']) ? $attributes['showFilterAge'] : true; |
| 27 | $show_rating = isset($attributes['showFilterRating']) ? $attributes['showFilterRating'] : true; |
| 28 | $show_sorting = isset($attributes['showSorting']) ? $attributes['showSorting'] : true; |
| 29 | $pagination_type = isset($attributes['paginationType']) ? $attributes['paginationType'] : 'numbers'; |
| 30 | $columns = isset($attributes['columns']) ? $attributes['columns'] : 3; |
| 31 | |
| 32 | $block_id = isset($attributes['blockId']) ? $attributes['blockId'] : ''; |
| 33 | $anchor = isset($attributes['anchor']) ? $attributes['anchor'] : ''; |
| 34 | $element_id = !empty($anchor) ? $anchor : $block_id; |
| 35 | if (empty($element_id)) { |
| 36 | $element_id = 'awt-book-gallery-' . uniqid(); |
| 37 | } |
| 38 | |
| 39 | // Define SVGs |
| 40 | $icon_star = '<svg class="w-3 h-3 text-yellow-400" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M341.5 45.1C337.4 37.1 329.1 32 320.1 32C311.1 32 302.8 37.1 298.7 45.1L225.1 189.3L65.2 214.7C56.3 216.1 48.9 222.4 46.1 231C43.3 239.6 45.6 249 51.9 255.4L166.3 369.9L141.1 529.8C139.7 538.7 143.4 547.7 150.7 553C158 558.3 167.6 559.1 175.7 555L320.1 481.6L464.4 555C472.4 559.1 482.1 558.3 489.4 553C496.7 547.7 500.4 538.8 499 529.8L473.7 369.9L588.1 255.4C594.5 249 596.7 239.6 593.9 231C591.1 222.4 583.8 216.1 574.8 214.7L415 189.3L341.5 45.1z"/></svg>'; |
| 41 | $icon_search = '<svg class="w-4 h-4 text-gray-400 absolute left-4 top-3.5" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M480 272C480 317.9 465.1 360.3 440 394.7L566.6 521.4C579.1 533.9 579.1 554.2 566.6 566.7C554.1 579.2 533.8 579.2 521.3 566.7L394.7 440C360.3 465.1 317.9 480 272 480C157.1 480 64 386.9 64 272C64 157.1 157.1 64 272 64C386.9 64 480 157.1 480 272zM272 416C351.5 416 416 351.5 416 272C416 192.5 351.5 128 272 128C192.5 128 128 192.5 128 272C128 351.5 192.5 416 272 416z"/></svg>'; |
| 42 | $icon_chevron_up = '<svg class="w-3 h-3 text-gray-400 transition-transform duration-200" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M297.4 169.4C309.9 156.9 330.2 156.9 342.7 169.4L534.7 361.4C547.2 373.9 547.2 394.2 534.7 406.7C522.2 419.2 501.9 419.2 489.4 406.7L320 237.3L150.6 406.6C138.1 419.1 117.8 419.1 105.3 406.6C92.8 394.1 92.8 373.8 105.3 361.3L297.3 169.3z"/></svg>'; |
| 43 | $icon_arrow_left = '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg>'; |
| 44 | $icon_arrow_right = '<svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M471.1 297.4C483.6 309.9 483.6 330.2 471.1 342.7L279.1 534.7C266.6 547.2 246.3 547.2 233.8 534.7C221.3 522.2 221.3 501.9 233.8 489.4L403.2 320L233.9 150.6C221.4 138.1 221.4 117.8 233.9 105.3C246.4 92.8 266.7 92.8 279.2 105.3L471.2 297.3z"/></svg>'; |
| 45 | |
| 46 | $icon_pen = '<svg class="w-3 h-3 text-gray-400" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M432.5 82.3L382.4 132.4L507.7 257.7L557.8 207.6C579.7 185.7 579.7 150.3 557.8 128.4L511.7 82.3C489.8 60.4 454.4 60.4 432.5 82.3zM343.3 161.2L342.8 161.3L198.7 204.5C178.8 210.5 163 225.7 156.4 245.5L67.8 509.8C64.9 518.5 65.9 528 70.3 535.8L225.7 380.4C224.6 376.4 224.1 372.3 224.1 368C224.1 341.5 245.6 320 272.1 320C298.6 320 320.1 341.5 320.1 368C320.1 394.5 298.6 416 272.1 416C267.8 416 263.6 415.4 259.7 414.4L104.3 569.7C112.1 574.1 121.5 575.1 130.3 572.2L394.6 483.6C414.3 477 429.6 461.2 435.6 441.3L478.8 297.2L478.9 296.7L343.4 161.2z"/></svg>'; |
| 47 | $icon_cart = '<svg class="w-3 h-3" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 24C0 10.7 10.7 0 24 0H69.5c22 0 41.5 12.8 50.6 32h411c26.3 0 45.5 25 38.6 50.4l-41 152.3c-8.5 31.4-37 53.3-69.5 53.3H170.7l5.4 28.5c2.2 11.3 12.1 19.5 23.6 19.5H488c13.3 0 24 10.7 24 24s-10.7 24-24 24H199.7c-34.6 0-64.3-24.6-70.7-58.5L77.4 54.5c-.7-3.8-4-6.5-7.9-6.5H24C10.7 48 0 37.3 0 24zM128 464a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm336-48a48 48 0 1 1 0 96 48 48 0 1 1 0-96z"/></svg>'; |
| 48 | $icon_sliders = '<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M0 416c0 17.7 14.3 32 32 32l54.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48L480 448c17.7 0 32-14.3 32-32s-14.3-32-32-32l-246.7 0c-12.3-28.3-40.5-48-73.3-48s-61 19.7-73.3 48L32 384c-17.7 0-32 14.3-32 32zm192 0a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM384 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM512 128c0-17.7-14.3-32-32-32l-54.7 0c-12.3-28.3-40.5-48-73.3-48s-61 19.7-73.3 48L32 96C14.3 96 0 110.3 0 128s14.3 32 32 32l246.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48L480 160c17.7 0 32-14.3 32-32zM160 256a32 32 0 1 0 0-64 32 32 0 1 0 0 64z"/></svg>'; |
| 49 | $icon_x_mark = '<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 384 512" xmlns="http://www.w3.org/2000/svg"><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>'; |
| 50 | |
| 51 | // Context Detection |
| 52 | $current_tax = ''; |
| 53 | $current_term_id = ''; |
| 54 | |
| 55 | $queried_object = get_queried_object(); |
| 56 | if ($queried_object instanceof WP_Term) { |
| 57 | if ($queried_object->taxonomy === 'book-category') { |
| 58 | $current_tax = 'book-category'; |
| 59 | $current_term_id = $queried_object->term_id; |
| 60 | } elseif ($queried_object->taxonomy === 'book-author') { |
| 61 | $current_tax = 'book-author'; |
| 62 | $current_term_id = $queried_object->term_id; |
| 63 | } elseif ($queried_object->taxonomy === 'book-series') { |
| 64 | $current_tax = 'book-series'; |
| 65 | $current_term_id = $queried_object->term_id; |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | // Initial Query for SEO |
| 70 | $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; |
| 71 | $args = array( |
| 72 | 'post_type' => 'book', |
| 73 | 'posts_per_page' => $items_per_page, |
| 74 | 'post_status' => 'publish', |
| 75 | 'paged' => $paged, |
| 76 | ); |
| 77 | |
| 78 | // Inject Context into Initial Query |
| 79 | if (!empty($current_tax) && !empty($current_term_id)) { |
| 80 | $args['tax_query'] = array( |
| 81 | array( |
| 82 | 'taxonomy' => $current_tax, |
| 83 | 'field' => 'term_id', |
| 84 | 'terms' => $current_term_id, |
| 85 | ) |
| 86 | ); |
| 87 | } |
| 88 | $book_query = new WP_Query($args); |
| 89 | $total_books = $book_query->found_posts; |
| 90 | $start_result = ($paged - 1) * $items_per_page + 1; |
| 91 | $end_result = min($paged * $items_per_page, $total_books); |
| 92 | |
| 93 | $wrapper_attributes = get_block_wrapper_attributes([ |
| 94 | 'class' => 'awt-book-gallery bg-white', |
| 95 | 'id' => $element_id |
| 96 | ]); |
| 97 | |
| 98 | // Helper to get Unique Meta Values (for filters) |
| 99 | if (!function_exists('awt_get_meta_options')) { |
| 100 | function awt_get_meta_options($key) { |
| 101 | global $wpdb; |
| 102 | $results = $wpdb->get_col($wpdb->prepare(" |
| 103 | SELECT DISTINCT meta_value FROM $wpdb->postmeta |
| 104 | WHERE meta_key = %s AND meta_value != '' |
| 105 | ", $key)); |
| 106 | return $results ? $results : []; |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | |
| 111 | // Helper to Render Multi-Select Dropdown |
| 112 | if (!function_exists('awt_render_dropdown_filter')) { |
| 113 | function awt_render_dropdown_filter($label, $name, $options, $placeholder = 'Search...', $icon_chevron = '') { |
| 114 | $key = uniqid(); |
| 115 | // Normalize options to [['value' =>, 'label' =>, 'count' => (optional)]] |
| 116 | $normalized_options = []; |
| 117 | |
| 118 | if (!empty($options)) { |
| 119 | // Check if it's an array of objects (Terms) or array of arrays |
| 120 | $first = reset($options); |
| 121 | if (is_array($first) && isset($first['value']) && isset($first['label'])) { |
| 122 | // Already in correct format (e.g. Genre custom array from previous step) |
| 123 | $normalized_options = $options; |
| 124 | } elseif (is_object($first) && isset($first->term_id)) { |
| 125 | // WP Terms Object |
| 126 | foreach ($options as $term) { |
| 127 | $normalized_options[] = [ |
| 128 | 'value' => $term->term_id, |
| 129 | 'label' => $term->name, |
| 130 | 'count' => $term->count |
| 131 | ]; |
| 132 | } |
| 133 | } elseif (!is_array($first) && !is_object($first)) { |
| 134 | // Simple Key-Value Pair (e.g. Price, Rating, Meta Unique Values) |
| 135 | // Note: awt_get_meta_options returns simple array of strings [val1, val2] |
| 136 | // But manual arrays are [key => label]. |
| 137 | // If keys are indices (0,1,2), it's a simple list. If keys are string/meaningful, it's key=>label. |
| 138 | |
| 139 | // Check if associative |
| 140 | $is_assoc = array_keys($options) !== range(0, count($options) - 1); |
| 141 | |
| 142 | foreach ($options as $k => $v) { |
| 143 | if ($is_assoc) { |
| 144 | // Key => Label (Price: '0-10' => 'Under $10') |
| 145 | $normalized_options[] = ['value' => $k, 'label' => $v]; |
| 146 | } else { |
| 147 | // Value only (Meta: 'Hardcover', 'Paperback') |
| 148 | $normalized_options[] = ['value' => $v, 'label' => $v]; |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | ?> |
| 154 | <div class="awt-custom-dropdown relative mb-4 group" id="dropdown-<?php echo esc_attr($key); ?>"> |
| 155 | <label class="block text-xs font-bold text-primary uppercase tracking-widest mb-2"><?php echo esc_html($label); ?></label> |
| 156 | |
| 157 | <button type="button" class="awt-dropdown-trigger w-full bg-white border border-gray-200 rounded px-3 py-2 text-sm text-left flex justify-between items-center hover:border-accent transition group-focus-within:border-accent"> |
| 158 | <span class="truncate text-secondary select-label font-medium">Select <?php echo esc_html($label); ?></span> |
| 159 | <span class="transform transition-transform duration-200 dropdown-icon origin-center"> |
| 160 | <?php echo $icon_chevron; ?> |
| 161 | </span> |
| 162 | </button> |
| 163 | |
| 164 | <div class="awt-dropdown-content hidden absolute top-full left-0 w-full bg-white border border-gray-200 shadow-xl rounded-b-lg z-50 mt-1 max-h-60 overflow-y-auto p-2"> |
| 165 | <input type="text" class="awt-dropdown-search w-full text-xs border border-gray-200 rounded px-2 py-2 mb-2 focus:outline-none focus:border-accent" placeholder="<?php echo esc_attr($placeholder); ?>"> |
| 166 | |
| 167 | <div class="space-y-0.5 awt-dropdown-list"> |
| 168 | <?php if (empty($normalized_options)): ?> |
| 169 | <div class="p-2 text-xs text-gray-400 italic">No options available</div> |
| 170 | <?php else: ?> |
| 171 | <?php foreach ($normalized_options as $opt) : ?> |
| 172 | <label class="flex items-center gap-2 cursor-pointer hover:bg-gray-50 p-1.5 rounded group transition w-full"> |
| 173 | <input type="checkbox" name="<?php echo esc_attr($name); ?>[]" value="<?php echo esc_attr($opt['value']); ?>" data-label="<?php echo esc_attr($opt['label']); ?>" class="rounded border-gray-300 text-accent focus:ring-accent w-4 h-4"> |
| 174 | <span class="text-xs text-secondary group-hover:text-accent transition font-medium"> |
| 175 | <?php echo esc_html($opt['label']); ?> |
| 176 | <?php if (isset($opt['count']) && $opt['count'] !== ''): ?> |
| 177 | <span class="text-gray-400 font-normal ml-1">(<?php echo esc_html($opt['count']); ?>)</span> |
| 178 | <?php endif; ?> |
| 179 | </span> |
| 180 | </label> |
| 181 | <?php endforeach; ?> |
| 182 | <?php endif; ?> |
| 183 | </div> |
| 184 | </div> |
| 185 | </div> |
| 186 | <?php |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | $formats = awt_get_meta_options('_rsbs_book_format'); |
| 191 | $languages = awt_get_meta_options('_rsbs_book_language'); |
| 192 | $years = awt_get_meta_options('_rsbs_book_publish_year'); |
| 193 | $ages = awt_get_meta_options('_rsbs_book_reading_age'); |
| 194 | $publishers = awt_get_meta_options('_rsbs_book_publisher_name'); // New |
| 195 | ?> |
| 196 | |
| 197 | <section <?php echo $wrapper_attributes; ?>> |
| 198 | <!-- Hidden inputs for JS --> |
| 199 | <input type="hidden" id="awt-ajax-url" value="<?php echo admin_url('admin-ajax.php'); ?>"> |
| 200 | <input type="hidden" class="awt-items-per-page" value="<?php echo esc_attr($items_per_page); ?>"> |
| 201 | <input type="hidden" id="awt-current-tax" value="<?php echo esc_attr($current_tax); ?>"> |
| 202 | <input type="hidden" id="awt-current-term" value="<?php echo esc_attr($current_term_id); ?>"> |
| 203 | <input type="hidden" class="awt-pagination-type" value="<?php echo esc_attr($pagination_type); ?>"> |
| 204 | |
| 205 | <div class="py-12"> |
| 206 | <div class="awt-container"> |
| 207 | <div class="grid grid-cols-12 md:grid-cols-12 gap-8 md:gap-12 items-start"> |
| 208 | |
| 209 | <?php if ($show_sidebar) : ?> |
| 210 | <!-- Mobile Filter Toggle --> |
| 211 | <?php if (!$is_editor) : ?> |
| 212 | <div class="block md:hidden w-full mb-6"> |
| 213 | <button id="awt-mobile-filter-toggle" class="w-full flex items-center justify-center bg-white border border-gray-200 text-primary font-bold py-3 px-4 rounded-lg shadow-sm hover:border-accent hover:text-accent transition"> |
| 214 | <?php echo $icon_sliders; ?> |
| 215 | <?php _e('Filters', 'author-website-templates'); ?> |
| 216 | </button> |
| 217 | <!-- Backdrop --> |
| 218 | <div id="awt-filter-backdrop" class="fixed inset-0 bg-black/50 z-40 hidden transition-opacity duration-300"></div> |
| 219 | </div> |
| 220 | <?php endif; ?> |
| 221 | |
| 222 | <?php |
| 223 | $aside_classes = $is_editor |
| 224 | ? 'awt-book-filters w-full md:space-y-0 md:col-span-3 space-y-8 static z-auto bg-transparent translate-x-0 overflow-visible p-0 h-auto shadow-none' |
| 225 | : 'awt-book-filters w-full md:space-y-0 md:col-span-3 space-y-8 fixed inset-0 z-50 bg-white transform -translate-x-full transition-transform duration-300 md:static md:z-auto md:bg-transparent md:translate-x-0 overflow-y-auto md:overflow-visible p-6 md:p-0 h-full md:h-auto shadow-2xl md:shadow-none'; |
| 226 | ?> |
| 227 | <aside class="<?php echo esc_attr($aside_classes); ?>"> |
| 228 | |
| 229 | <!-- Mobile Header with Close --> |
| 230 | <?php if (!$is_editor) : ?> |
| 231 | <div class="flex items-center justify-between mb-6 md:hidden"> |
| 232 | <h2 class="text-xl font-bold text-primary font-serif"><?php _e('Filters', 'author-website-templates'); ?></h2> |
| 233 | <button id="awt-mobile-filter-close" class="text-gray-400 hover:text-accent p-2"> |
| 234 | <?php echo $icon_x_mark; ?> |
| 235 | </button> |
| 236 | </div> |
| 237 | <?php endif; ?> |
| 238 | |
| 239 | <!-- Search --> |
| 240 | <?php if($show_search): ?> |
| 241 | <div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100"> |
| 242 | <h3 class="font-bold text-primary text-sm uppercase tracking-wider mb-4"><?php _e('Search', 'author-website-templates'); ?></h3> |
| 243 | <div class="relative"> |
| 244 | <input type="text" class="awt-filter-search w-full pl-10 pr-4 py-3 bg-paper border border-gray-200 rounded-lg focus:outline-none focus:border-accent text-sm transition" placeholder="<?php _e('Title, keyword...', 'author-website-templates'); ?>"> |
| 245 | <?php echo $icon_search; ?> |
| 246 | </div> |
| 247 | </div> |
| 248 | <?php endif; ?> |
| 249 | |
| 250 | <div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100"> |
| 251 | |
| 252 | <!-- Genre Filter --> |
| 253 | <?php if($show_genre): ?> |
| 254 | <div class="mb-8"> |
| 255 | <?php |
| 256 | if ($current_tax === 'book-category' && !empty($current_term_id)) { |
| 257 | // Locked View |
| 258 | $current_term = get_term($current_term_id); |
| 259 | if ($current_term) { |
| 260 | ?> |
| 261 | <h3 class="font-bold text-primary text-sm uppercase tracking-wider mb-4"><?php _e('Genres', 'author-website-templates'); ?></h3> |
| 262 | <label class="flex items-center gap-3 cursor-not-allowed opacity-75"> |
| 263 | <input type="checkbox" checked disabled class="w-4 h-4 text-accent border-gray-300 rounded"> |
| 264 | <span class="text-sm text-secondary font-bold"><?php echo esc_html($current_term->name); ?></span> |
| 265 | </label> |
| 266 | <a href="<?php echo $back_link; ?>" class="text-xs font-bold text-accent hover:underline mt-2 inline-flex items-center gap-1"> |
| 267 | <?php echo $icon_arrow_left; ?> <?php _e('Back to All Books', 'author-website-templates'); ?> |
| 268 | </a> |
| 269 | <?php |
| 270 | } |
| 271 | } else { |
| 272 | // Dropdown View |
| 273 | $genres = get_terms(['taxonomy' => 'book-category', 'hide_empty' => true]); |
| 274 | awt_render_dropdown_filter(__('Genres', 'author-website-templates'), 'genre', $genres, 'Search genres...', $icon_chevron_up); |
| 275 | } |
| 276 | ?> |
| 277 | </div> |
| 278 | <?php endif; ?> |
| 279 | |
| 280 | <!-- Authors Filter --> |
| 281 | <?php if($show_author): ?> |
| 282 | <div class="mb-8"> |
| 283 | <?php |
| 284 | if ($current_tax === 'book-author' && !empty($current_term_id)) { |
| 285 | $current_term = get_term($current_term_id); |
| 286 | if ($current_term) { |
| 287 | ?> |
| 288 | <h3 class="font-bold text-primary text-sm uppercase tracking-wider mb-4"><?php _e('Authors', 'author-website-templates'); ?></h3> |
| 289 | <label class="flex items-center gap-3 cursor-not-allowed opacity-75"> |
| 290 | <input type="checkbox" checked disabled class="w-4 h-4 text-accent border-gray-300 rounded"> |
| 291 | <span class="text-sm text-secondary font-bold"><?php echo esc_html($current_term->name); ?></span> |
| 292 | </label> |
| 293 | <a href="<?php echo $back_link; ?>" class="text-xs font-bold text-accent hover:underline mt-2 inline-flex items-center gap-1"> |
| 294 | <?php echo $icon_arrow_left; ?> <?php _e('Back to All Books', 'author-website-templates'); ?> |
| 295 | </a> |
| 296 | <?php |
| 297 | } |
| 298 | } else { |
| 299 | $authors = get_terms(['taxonomy' => 'book-author', 'hide_empty' => true]); |
| 300 | awt_render_dropdown_filter(__('Authors', 'author-website-templates'), 'author', $authors, 'Search authors...', $icon_chevron_up); |
| 301 | } |
| 302 | ?> |
| 303 | </div> |
| 304 | <?php endif; ?> |
| 305 | |
| 306 | <!-- Series Filter --> |
| 307 | <?php if($show_series): ?> |
| 308 | <div class="mb-8"> |
| 309 | <?php |
| 310 | if ($current_tax === 'book-series' && !empty($current_term_id)) { |
| 311 | $current_term = get_term($current_term_id); |
| 312 | if ($current_term) { |
| 313 | ?> |
| 314 | <h3 class="font-bold text-primary text-sm uppercase tracking-wider mb-4"><?php _e('Series', 'author-website-templates'); ?></h3> |
| 315 | <label class="flex items-center gap-3 cursor-not-allowed opacity-75"> |
| 316 | <input type="checkbox" checked disabled class="w-4 h-4 text-accent border-gray-300 rounded"> |
| 317 | <span class="text-sm text-secondary font-bold"><?php echo esc_html($current_term->name); ?></span> |
| 318 | </label> |
| 319 | <a href="<?php echo $back_link; ?>" class="text-xs font-bold text-accent hover:underline mt-2 inline-flex items-center gap-1"> |
| 320 | <?php echo $icon_arrow_left; ?> <?php _e('Back to All Books', 'author-website-templates'); ?> |
| 321 | </a> |
| 322 | <?php |
| 323 | } |
| 324 | } else { |
| 325 | $series = get_terms(['taxonomy' => 'book-series', 'hide_empty' => true]); |
| 326 | awt_render_dropdown_filter(__('Series', 'author-website-templates'), 'series', $series, 'Search series...', $icon_chevron_up); |
| 327 | } |
| 328 | ?> |
| 329 | </div> |
| 330 | <?php endif; ?> |
| 331 | |
| 332 | <!-- Format Filter (Meta) --> |
| 333 | <?php if($show_format && !empty($formats)): ?> |
| 334 | <div class="mb-8"> |
| 335 | <?php awt_render_dropdown_filter(__('Format', 'author-website-templates'), 'format', $formats, 'Search format...', $icon_chevron_up); ?> |
| 336 | </div> |
| 337 | <?php endif; ?> |
| 338 | |
| 339 | <!-- Language Filter (Meta) --> |
| 340 | <?php if($show_language && !empty($languages)): ?> |
| 341 | <div class="mb-8"> |
| 342 | <?php awt_render_dropdown_filter(__('Language', 'author-website-templates'), 'language', $languages, 'Search language...', $icon_chevron_up); ?> |
| 343 | </div> |
| 344 | <?php endif; ?> |
| 345 | |
| 346 | <!-- Publisher Filter (Meta) --> |
| 347 | <?php if($show_publisher && !empty($publishers)): ?> |
| 348 | <div class="mb-8"> |
| 349 | <?php |
| 350 | awt_render_dropdown_filter(__('Publisher', 'author-website-templates'), 'publisher', $publishers, 'Search publishers...', $icon_chevron_up); |
| 351 | ?> |
| 352 | </div> |
| 353 | <?php endif; ?> |
| 354 | |
| 355 | <!-- ISBN Filter (Meta Input) --> |
| 356 | <?php if($show_isbn): ?> |
| 357 | <div class="mb-8"> |
| 358 | <h3 class="font-bold text-primary text-sm uppercase tracking-wider mb-4 flex justify-between cursor-pointer awt-accordion-trigger"> |
| 359 | <?php _e('ISBN', 'author-website-templates'); ?> <?php echo $icon_chevron_up; ?> |
| 360 | </h3> |
| 361 | <div class="space-y-3 awt-accordion-content"> |
| 362 | <div class="relative"> |
| 363 | <input type="text" class="awt-filter-isbn w-full pl-10 pr-4 py-2 bg-paper border border-gray-200 rounded-lg focus:outline-none focus:border-accent text-sm transition" placeholder="<?php _e('ISBN-10 or ISBN-13', 'author-website-templates'); ?>"> |
| 364 | <?php echo $icon_search; ?> |
| 365 | </div> |
| 366 | </div> |
| 367 | </div> |
| 368 | <?php endif; ?> |
| 369 | |
| 370 | <!-- Price Filter (Range Logic) --> |
| 371 | <?php if($show_price): ?> |
| 372 | <div class="mb-8"> |
| 373 | <?php |
| 374 | $price_ranges = [ |
| 375 | '0-10' => 'Under $10', |
| 376 | '10-20' => '$10 - $20', |
| 377 | '20-30' => '$20 - $30', |
| 378 | '30-50' => '$30 - $50', |
| 379 | '50+' => '$50+' |
| 380 | ]; |
| 381 | awt_render_dropdown_filter(__('Price', 'author-website-templates'), 'price', $price_ranges, 'Search prices...', $icon_chevron_up); |
| 382 | ?> |
| 383 | </div> |
| 384 | <?php endif; ?> |
| 385 | |
| 386 | <!-- Year Filter (Meta) --> |
| 387 | <?php if($show_year && !empty($years)): ?> |
| 388 | <div class="mb-8"> |
| 389 | <?php |
| 390 | // Sort years desc |
| 391 | rsort($years); |
| 392 | awt_render_dropdown_filter(__('Publish Year', 'author-website-templates'), 'year', $years, 'Search years...', $icon_chevron_up); |
| 393 | ?> |
| 394 | </div> |
| 395 | <?php endif; ?> |
| 396 | |
| 397 | <!-- Age Filter (Meta) --> |
| 398 | <?php if($show_age && !empty($ages)): ?> |
| 399 | <div class="mb-8"> |
| 400 | <?php |
| 401 | awt_render_dropdown_filter(__('Reading Age', 'author-website-templates'), 'age', $ages, 'Search reading age...', $icon_chevron_up); |
| 402 | ?> |
| 403 | </div> |
| 404 | <?php endif; ?> |
| 405 | |
| 406 | <!-- Rating Filter (Meta Logic) --> |
| 407 | <?php if($show_rating): ?> |
| 408 | <div class="mb-8"> |
| 409 | <?php |
| 410 | $rating_options = [ |
| 411 | '5' => '5 Stars', |
| 412 | '4' => '4 Stars & Up', |
| 413 | '3' => '3 Stars & Up' |
| 414 | ]; |
| 415 | awt_render_dropdown_filter(__('Rating', 'author-website-templates'), 'rating', $rating_options, 'Search ratings...', $icon_chevron_up); |
| 416 | ?> |
| 417 | </div> |
| 418 | <?php endif; ?> |
| 419 | |
| 420 | <button class="awt-apply-filters w-full py-3 bg-primary text-white text-xs font-bold uppercase rounded hover:bg-slate-800 transition shadow-lg shadow-blue-900/10"> |
| 421 | <?php _e('Apply Filters', 'author-website-templates'); ?> |
| 422 | </button> |
| 423 | <button class="awt-reset-filters w-full py-3 mt-2 text-gray-400 text-xs font-bold uppercase hover:text-accent transition text-white"> |
| 424 | <?php _e('Reset All', 'author-website-templates'); ?> |
| 425 | </button> |
| 426 | |
| 427 | </div> |
| 428 | </aside> |
| 429 | <?php endif; ?> |
| 430 | |
| 431 | <div class="<?php echo $show_sidebar ? 'md:col-span-9' : 'md:col-span-12'; ?>"> |
| 432 | |
| 433 | <!-- Top Bar --> |
| 434 | <div class="flex flex-col sm:flex-row justify-between items-center mb-8 bg-white p-4 rounded-lg shadow-sm border border-gray-100"> |
| 435 | <p class="text-sm text-secondary font-medium mb-3 sm:mb-0 awt-files-result-count"> |
| 436 | Showing <span class="font-bold text-primary"><?php echo $start_result; ?> - <?php echo $end_result; ?></span> of <span class="font-bold text-primary"><?php echo $total_books; ?></span> Results |
| 437 | </p> |
| 438 | <?php if($show_sorting): ?> |
| 439 | <div class="flex items-center gap-3"> |
| 440 | <span class="text-xs font-bold text-gray-400 uppercase"><?php _e('Sort By:', 'author-website-templates'); ?></span> |
| 441 | <select class="awt-sort-books bg-paper border border-gray-200 text-primary text-sm rounded px-3 py-2 focus:outline-none focus:border-accent cursor-pointer transition"> |
| 442 | <option value="date_desc"><?php _e('Newest Arrivals', 'author-website-templates'); ?></option> |
| 443 | <option value="price_asc"><?php _e('Price: Low to High', 'author-website-templates'); ?></option> |
| 444 | <option value="price_desc"><?php _e('Price: High to Low', 'author-website-templates'); ?></option> |
| 445 | <option value="rating_desc"><?php _e('Top Rated', 'author-website-templates'); ?></option> |
| 446 | </select> |
| 447 | </div> |
| 448 | <?php endif; ?> |
| 449 | </div> |
| 450 | |
| 451 | <!-- Book Grid --> |
| 452 | <div class="awt-book-grid-container grid gap-8" style="grid-template-columns: repeat(<?php echo intval($columns); ?>, minmax(0, 1fr));"> |
| 453 | <?php |
| 454 | if ($book_query->have_posts()) : |
| 455 | while ($book_query->have_posts()) : $book_query->the_post(); |
| 456 | $book_id = get_the_ID(); |
| 457 | |
| 458 | // --- 1. Get Initial Prices from Meta --- |
| 459 | $raw_price = get_post_meta($book_id, '_rsbs_book_price', true); |
| 460 | $raw_sale_price = get_post_meta($book_id, '_rsbs_book_sale_price', true); |
| 461 | |
| 462 | // Clean data to ensure they are numbers |
| 463 | $regular_price = (float) preg_replace('/[^0-9.]/', '', $raw_price); |
| 464 | $sale_price = (float) preg_replace('/[^0-9.]/', '', $raw_sale_price); |
| 465 | |
| 466 | // --- 2. Linked Product Override (Your Logic) --- |
| 467 | if(function_exists('rswpbs_get_linked_product')){ |
| 468 | $linked_product = rswpbs_get_linked_product(); |
| 469 | if ($linked_product) { |
| 470 | $regular_price = $linked_product->get_regular_price(); |
| 471 | $sale_price = $linked_product->get_sale_price(); |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | // --- 3. Calculate Logic --- |
| 476 | // Check if there is a valid sale |
| 477 | $has_sale = !empty($sale_price) && $sale_price < $regular_price && $sale_price > 0; |
| 478 | |
| 479 | // Determine Price to show |
| 480 | $display_price = $has_sale ? $sale_price : $regular_price; |
| 481 | |
| 482 | // Calculate Savings Percentage |
| 483 | $savings_pct = 0; |
| 484 | if ($has_sale && $regular_price > 0) { |
| 485 | $savings_pct = round((($regular_price - $sale_price) / $regular_price) * 100); |
| 486 | } |
| 487 | |
| 488 | // Other Data |
| 489 | $rating = get_post_meta($book_id, '_rsbs_average_book_rating', true); |
| 490 | if (!is_numeric($rating)) $rating = 0; |
| 491 | |
| 492 | $author_terms = get_the_terms($book_id, 'book-author'); |
| 493 | $author_name = $author_terms ? $author_terms[0]->name : 'Unknown Author'; |
| 494 | $cat_terms = get_the_terms($book_id, 'book-category'); |
| 495 | $cat_name = $cat_terms ? $cat_terms[0]->name : ''; |
| 496 | |
| 497 | $img_url = get_the_post_thumbnail_url($book_id, 'large'); |
| 498 | $short_desc = get_post_meta($book_id, '_rswpbs_short_description', true); |
| 499 | $permalink = get_permalink(); |
| 500 | $buy_links = get_post_meta($book_id, 'rswpbs_also_available_website_list', true); |
| 501 | $buy_btn_text = get_post_meta($book_id, '_rsbs_buy_btn_text', true); |
| 502 | $buy_btn_link = get_post_meta($book_id, '_rsbs_buy_btn_link', true); |
| 503 | $format_val = get_post_meta($book_id, '_rsbs_book_format', true); |
| 504 | ?> |
| 505 | <div class="group bg-white rounded-xl shadow-sm hover:shadow-xl hover:-translate-y-1 transition duration-300 overflow-hidden border border-gray-100 flex flex-col"> |
| 506 | <div class="relative p-6 bg-[#f1f5f9] flex justify-center items-center h-64 overflow-hidden"> |
| 507 | <?php if($format_val): ?> |
| 508 | <span class="absolute top-4 left-4 bg-accent text-white text-[10px] font-bold px-2 py-1 rounded uppercase z-10"><?php echo esc_html($format_val); ?></span> |
| 509 | <?php endif; ?> |
| 510 | |
| 511 | <?php if($img_url): ?> |
| 512 | <img src="<?php echo esc_url($img_url); ?>" class="h-48 shadow-lg rounded transform group-hover:scale-105 transition duration-500"> |
| 513 | <?php else: ?> |
| 514 | <div class="h-48 w-32 bg-gray-200 shadow-lg rounded flex items-center justify-center text-gray-400 text-xs">No Image</div> |
| 515 | <?php endif; ?> |
| 516 | </div> |
| 517 | |
| 518 | <div class="p-5 flex-1 flex flex-col"> |
| 519 | |
| 520 | <div class="mb-3 flex justify-between items-start"> |
| 521 | <span class="text-[10px] font-bold text-accent uppercase tracking-widest px-1 py-0.5 rounded mt-1"> |
| 522 | <?php echo esc_html($cat_name); ?> |
| 523 | </span> |
| 524 | |
| 525 | <div class="flex flex-col items-end"> |
| 526 | <?php if ($has_sale) : ?> |
| 527 | <span class="text-[10px] font-bold text-emerald-600 bg-emerald-50 px-1.5 py-0.5 rounded mb-1"> |
| 528 | Save <?php echo $savings_pct; ?>% |
| 529 | </span> |
| 530 | <div class="flex items-center gap-1.5 leading-none"> |
| 531 | <span class="text-xs text-gray-400 line-through decoration-gray-400"> |
| 532 | $<?php echo number_format($regular_price, 2); ?> |
| 533 | </span> |
| 534 | <span class="text-sm font-bold text-primary"> |
| 535 | $<?php echo number_format($sale_price, 2); ?> |
| 536 | </span> |
| 537 | </div> |
| 538 | <?php else : ?> |
| 539 | <span class="text-sm font-bold text-primary mt-1"> |
| 540 | <?php echo $display_price > 0 ? '$' . number_format($display_price, 2) : 'Free'; ?> |
| 541 | </span> |
| 542 | <?php endif; ?> |
| 543 | </div> |
| 544 | </div> |
| 545 | |
| 546 | <h3 class="text-xl font-serif font-bold text-primary mb-1 group-hover:text-accent transition"> |
| 547 | <a href="<?php echo esc_url($permalink); ?>"><?php the_title(); ?></a> |
| 548 | </h3> |
| 549 | |
| 550 | <div class="flex items-center mb-2"> |
| 551 | <div class="flex text-yellow-400 text-xs gap-0.5"> |
| 552 | <?php for($i=1; $i<=5; $i++) { |
| 553 | echo $i <= $rating ? $icon_star : str_replace('text-yellow-400', 'text-gray-300', $icon_star); |
| 554 | } ?> |
| 555 | </div> |
| 556 | <span class="text-[10px] text-gray-400 font-medium ml-1.5">(<?php echo esc_html($rating); ?>)</span> |
| 557 | </div> |
| 558 | |
| 559 | <div class="flex items-center gap-2 mb-3"> |
| 560 | <?php echo $icon_pen; ?> |
| 561 | <span class="text-xs font-bold text-secondary"><?php echo esc_html($author_name); ?></span> |
| 562 | </div> |
| 563 | |
| 564 | <p class="text-xs text-secondary mb-4 line-clamp-3 leading-relaxed"><?php echo esc_html(wp_trim_words($short_desc, 20)); ?></p> |
| 565 | |
| 566 | <div class="mt-auto space-y-3"> |
| 567 | <div class="flex flex-wrap gap-2"> |
| 568 | <?php |
| 569 | echo '<a target="_blank" href="'.esc_url($buy_btn_link).'" |
| 570 | class="flex-1 min-w-[110px] flex items-center justify-center gap-1 py-2 |
| 571 | bg-gray-50 border border-gray-200 rounded text-xs font-bold text-primary |
| 572 | hover:bg-white hover:border-[#FF9900] hover:text-[#FF9900] transition">' |
| 573 | . esc_html($buy_btn_text) . |
| 574 | '</a>'; |
| 575 | |
| 576 | if (!empty($buy_links)) { |
| 577 | foreach (array_slice($buy_links, 0, 4) as $link) { |
| 578 | echo '<a target="_blank" href="'.esc_url($link['book_url']).'" |
| 579 | class="flex-1 min-w-[110px] flex items-center justify-center gap-1 py-2 |
| 580 | bg-gray-50 border border-gray-200 rounded text-xs font-bold text-primary |
| 581 | hover:bg-white hover:border-[#FF9900] hover:text-[#FF9900] transition">' |
| 582 | . esc_html($link['website_name']) . |
| 583 | '</a>'; |
| 584 | } |
| 585 | } |
| 586 | ?> |
| 587 | </div> |
| 588 | |
| 589 | <div class="flex items-center gap-2 w-full"> |
| 590 | |
| 591 | <?php |
| 592 | // 1. Shortcode Check & Output |
| 593 | if ( shortcode_exists('rswpbs_book_loop_btn') ) { |
| 594 | echo do_shortcode( '[rswpbs_book_loop_btn]' ); |
| 595 | } |
| 596 | ?> |
| 597 | |
| 598 | <a href="<?php echo esc_url($permalink); ?>" class="flex-1 block py-2.5 border border-primary text-primary text-center text-xs font-bold uppercase rounded hover:bg-primary hover:text-white transition"> |
| 599 | <?php _e('View Details', 'author-website-templates'); ?> |
| 600 | </a> |
| 601 | </div> |
| 602 | |
| 603 | </div> |
| 604 | </div> |
| 605 | </div> |
| 606 | <?php endwhile; wp_reset_postdata(); ?> |
| 607 | <?php else: ?> |
| 608 | <p class="col-span-3 text-center text-gray-500 py-12"><?php _e('No books found matching your criteria.', 'author-website-templates'); ?></p> |
| 609 | <?php endif; ?> |
| 610 | </div> |
| 611 | |
| 612 | <!-- Pagination --> |
| 613 | <!-- Note: Implementation simplified for View.js update --> |
| 614 | <div class="awt-pagination mt-16 flex justify-center gap-2"> |
| 615 | <?php |
| 616 | $total_pages = $book_query->max_num_pages; |
| 617 | |
| 618 | if ($pagination_type === 'load_more') { |
| 619 | if ($total_pages > 1) { |
| 620 | echo '<div class="text-center w-full">'; // Centering container |
| 621 | echo '<button id="awt-load-more-btn" data-page="1" class="px-8 py-3 bg-white border border-gray-200 text-primary font-bold uppercase text-xs rounded shadow-sm hover:border-accent hover:text-accent transition">'; |
| 622 | _e('Load More Books', 'author-website-templates'); |
| 623 | echo '</button>'; |
| 624 | echo '</div>'; |
| 625 | } |
| 626 | } else { |
| 627 | // Numbers |
| 628 | if ($total_pages > 1) { |
| 629 | $current = max(1, get_query_var('paged')); |
| 630 | |
| 631 | // Prev |
| 632 | if ($current > 1) { |
| 633 | echo '<button data-page="'.($current-1).'" class="awt-page-link w-10 h-10 flex items-center justify-center rounded bg-white border border-gray-200 text-secondary hover:border-accent hover:text-accent transition font-bold text-sm">'.$icon_arrow_left.'</button>'; |
| 634 | } |
| 635 | |
| 636 | // Pages (Simplified range) |
| 637 | for ($i = 1; $i <= $total_pages; $i++) { |
| 638 | if ($i == $current) { |
| 639 | echo '<button class="w-10 h-10 flex items-center justify-center rounded bg-primary text-white font-bold text-sm">'.$i.'</button>'; |
| 640 | } else { |
| 641 | echo '<button data-page="'.$i.'" class="awt-page-link w-10 h-10 flex items-center justify-center rounded bg-white border border-gray-200 text-secondary hover:border-accent hover:text-accent transition font-bold text-sm">'.$i.'</button>'; |
| 642 | } |
| 643 | } |
| 644 | |
| 645 | // Next |
| 646 | if ($current < $total_pages) { |
| 647 | echo '<button data-page="'.($current+1).'" class="awt-page-link w-10 h-10 flex items-center justify-center rounded bg-white border border-gray-200 hover:border-accent hover:text-white text-primary hover:bg-primary transition font-bold text-sm">'.$icon_arrow_right.'</button>'; |
| 648 | } |
| 649 | } |
| 650 | } |
| 651 | ?> |
| 652 | </div> |
| 653 | |
| 654 | </div> |
| 655 | </div> |
| 656 | </div> |
| 657 | </div> |
| 658 | </section> |
| 659 |