UI.php
110 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Helpers for the Settings page. |
| 4 | * |
| 5 | * @package FrontBlocks |
| 6 | * @author Close <info@close.technology> |
| 7 | * @copyright 2025 Close |
| 8 | * @version 1.0.0 |
| 9 | */ |
| 10 | |
| 11 | namespace FrontBlocks\Admin; |
| 12 | |
| 13 | defined( 'ABSPATH' ) || exit; |
| 14 | |
| 15 | /** |
| 16 | * UI class for the Settings page. |
| 17 | */ |
| 18 | class UI { |
| 19 | |
| 20 | /** |
| 21 | * Show an info card for an always-active free feature (green, no toggle). |
| 22 | * |
| 23 | * @param string $icon_slug Icon slug resolved via get_feature_icon(). |
| 24 | * @param string $title Feature title. |
| 25 | * @param string $description Feature description. |
| 26 | * @return void |
| 27 | */ |
| 28 | public static function show_info_card( $icon_slug, $title, $description ) { |
| 29 | $icon = self::get_feature_icon( $icon_slug ); |
| 30 | ?> |
| 31 | <div class="frbl-feature-card frbl-feature-active"> |
| 32 | <div class="frbl-feature-content"> |
| 33 | <div class="frbl-feature-icon"> |
| 34 | <?php echo $icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> |
| 35 | </div> |
| 36 | <div class="frbl-feature-info"> |
| 37 | <h3 class="frbl-feature-title"> |
| 38 | <?php echo esc_html( $title ); ?> |
| 39 | </h3> |
| 40 | <p class="frbl-feature-description"> |
| 41 | <?php echo esc_html( $description ); ?> |
| 42 | </p> |
| 43 | </div> |
| 44 | </div> |
| 45 | </div> |
| 46 | <?php |
| 47 | } |
| 48 | |
| 49 | /** |
| 50 | * Show a PRO info card (red, locked, no toggle). |
| 51 | * Icon is read from assets/admin/icons/<slug>.svg. |
| 52 | * |
| 53 | * @param string $icon_slug SVG filename without extension. |
| 54 | * @param string $title Feature title. |
| 55 | * @param string $description Feature description. |
| 56 | * @return void |
| 57 | */ |
| 58 | public static function show_pro_info_card( $icon_slug, $title, $description ) { |
| 59 | $icon_path = FRBL_PLUGIN_PATH . 'assets/admin/icons/' . $icon_slug . '.svg'; |
| 60 | $icon_svg = file_exists( $icon_path ) ? file_get_contents( $icon_path ) : ''; // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents |
| 61 | $pro_url = 'https://close.technology/wordpress-plugins/frontblocks-pro/?utm_source=frontblocks&utm_medium=plugin&utm_campaign=settings-pro-card'; |
| 62 | ?> |
| 63 | <a href="<?php echo esc_url( $pro_url ); ?>" target="_blank" rel="noopener noreferrer" style="text-decoration: none; color: inherit; display: block;"> |
| 64 | <div class="frbl-feature-card frbl-feature-pro frbl-feature-pro-info" style="height: 100%;"> |
| 65 | <div class="frbl-pro-badge">PRO</div> |
| 66 | <div class="frbl-feature-content"> |
| 67 | <div class="frbl-feature-icon"> |
| 68 | <?php echo $icon_svg; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> |
| 69 | </div> |
| 70 | <div class="frbl-feature-info"> |
| 71 | <h3 class="frbl-feature-title"> |
| 72 | <?php echo esc_html( $title ); ?> |
| 73 | </h3> |
| 74 | <p class="frbl-feature-description"> |
| 75 | <?php echo esc_html( $description ); ?> |
| 76 | </p> |
| 77 | </div> |
| 78 | </div> |
| 79 | </div> |
| 80 | </a> |
| 81 | <?php |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * Get inline SVG icon for a free feature. |
| 86 | * |
| 87 | * @param string $icon_slug Icon slug. |
| 88 | * @return string SVG HTML. |
| 89 | */ |
| 90 | public static function get_feature_icon( $icon_slug ) { |
| 91 | $icons = array( |
| 92 | 'animations' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"/><path d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>', |
| 93 | 'carousel' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>', |
| 94 | 'gallery' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>', |
| 95 | 'sticky' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"/></svg>', |
| 96 | 'insert_post' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>', |
| 97 | 'counter' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 20l4-16m2 16l4-16M6 9h14M4 15h14"/></svg>', |
| 98 | 'reading_time' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>', |
| 99 | 'stacked_images' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="7" width="12" height="10" rx="1" transform="rotate(-5 9 12)"/><rect x="6" y="5" width="12" height="10" rx="1" transform="rotate(3 12 10)"/><rect x="9" y="3" width="12" height="10" rx="1"/></svg>', |
| 100 | 'product_categories' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"/></svg>', |
| 101 | 'headline_marquee' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 12h18M3 12l4-4m-4 4l4 4m14-4l-4-4m4 4l-4 4"/></svg>', |
| 102 | 'svg_upload' => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/><path d="M12 10v4m-2-2h4" stroke-linecap="round"/></svg>', |
| 103 | ); |
| 104 | |
| 105 | $default = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/></svg>'; |
| 106 | |
| 107 | return $icons[ $icon_slug ] ?? $default; |
| 108 | } |
| 109 | } |
| 110 |