From 885e3e6423638e08448cdabb4a54a89a76343531 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Tue, 17 Oct 2023 17:09:28 +0300 Subject: [PATCH 01/13] chore: add BF deal --- .../customizer-controls/src/@types/utils.d.ts | 11 + .../src/builder-upsell/Upsells.tsx | 19 + assets/apps/dashboard/src/Components/App.js | 6 + assets/apps/dashboard/src/Components/Deal.js | 17 + .../dashboard/src/scss/content/_start.scss | 25 ++ assets/img/dashboard/black-friday-banner.png | Bin 0 -> 28255 bytes .../black-friday-customizer-banner.png | Bin 0 -> 7102 bytes inc/admin/dashboard/main.php | 5 + inc/core/admin.php | 5 + inc/core/limited_offers.php | 339 ++++++++++++++++++ inc/customizer/loader.php | 3 + 11 files changed, 430 insertions(+) create mode 100644 assets/apps/dashboard/src/Components/Deal.js create mode 100644 assets/img/dashboard/black-friday-banner.png create mode 100644 assets/img/dashboard/black-friday-customizer-banner.png create mode 100644 inc/core/limited_offers.php diff --git a/assets/apps/customizer-controls/src/@types/utils.d.ts b/assets/apps/customizer-controls/src/@types/utils.d.ts index 41e1756532..8f06aedffb 100644 --- a/assets/apps/customizer-controls/src/@types/utils.d.ts +++ b/assets/apps/customizer-controls/src/@types/utils.d.ts @@ -114,6 +114,17 @@ declare global { nonce: string; hideConditionalHeaderSelector: boolean; dashUpdatesMessage: string; + deal?: { + active?: boolean; + dealSlug?: string; + urgencyText?: string; + remaningTime?: string; + bannerUrl?: string; + customizerBannerUrl?: string; + linkDashboard?: string; + linkGlobal?: string; + linkCustomizer?: string; + } }; NeveProReactCustomize: undefined | StringObjectKeys; } diff --git a/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx b/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx index b9a44f186f..3b7676564b 100644 --- a/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx +++ b/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx @@ -11,6 +11,25 @@ const Upsells: React.FC = ({ control }) => { const { params } = control; const { title, url } = params; + if ( window?.NeveReactCustomize?.deal?.active ) { + return ( +
+ + {'Black + +
+ ) + } + return (
{title && ( diff --git a/assets/apps/dashboard/src/Components/App.js b/assets/apps/dashboard/src/Components/App.js index cdce482050..eb9983e649 100644 --- a/assets/apps/dashboard/src/Components/App.js +++ b/assets/apps/dashboard/src/Components/App.js @@ -9,6 +9,7 @@ import { fetchOptions } from '../utils/rest'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { useState, Fragment, useEffect } from '@wordpress/element'; +import Deal from "./Deal"; const App = ({ setSettings, toast, currentTab, setTab }) => { const [loading, setLoading] = useState(true); @@ -27,6 +28,11 @@ const App = ({ setSettings, toast, currentTab, setTab }) => {
+ { + ( 'start' === currentTab ) && ( + + ) + } {'starter-sites' !== currentTab && }
diff --git a/assets/apps/dashboard/src/Components/Deal.js b/assets/apps/dashboard/src/Components/Deal.js new file mode 100644 index 0000000000..4540afb5ad --- /dev/null +++ b/assets/apps/dashboard/src/Components/Deal.js @@ -0,0 +1,17 @@ +const Deal = () => { + + if ( ! Boolean(window.neveDash?.deal?.active)) { + return <>; + } + + return ( + + ) +} + +export default Deal; diff --git a/assets/apps/dashboard/src/scss/content/_start.scss b/assets/apps/dashboard/src/scss/content/_start.scss index 02c6955db0..ef3321a6aa 100644 --- a/assets/apps/dashboard/src/scss/content/_start.scss +++ b/assets/apps/dashboard/src/scss/content/_start.scss @@ -48,3 +48,28 @@ } } } + +@import url('https://fonts.cdnfonts.com/css/barlow'); +.nv-deal { + margin-bottom: 10px; + display: flex; + + a { + position: relative; + } + + .nv-urgency { + position: absolute; + top: 15px; + left: 19px; + + color: #FFF; + font-family: Barlow, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", sans-serif; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: 0.3px; + text-transform: uppercase; + } +} diff --git a/assets/img/dashboard/black-friday-banner.png b/assets/img/dashboard/black-friday-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..173ec596f8952f699a090192ce9537bf3aa0ee0c GIT binary patch literal 28255 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 z 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 HTZH{T>V8$8 literal 0 HcmV?d00001 diff --git a/assets/img/dashboard/black-friday-customizer-banner.png b/assets/img/dashboard/black-friday-customizer-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..9ff77fb1566c7c9574276e629509ba54d1785d3d GIT binary patch literal 7102 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 literal 0 HcmV?d00001 diff --git a/inc/admin/dashboard/main.php b/inc/admin/dashboard/main.php index bc9cf741ab..bfd7c13e87 100755 --- a/inc/admin/dashboard/main.php +++ b/inc/admin/dashboard/main.php @@ -7,6 +7,7 @@ namespace Neve\Admin\Dashboard; +use Neve\Core\Limited_Offers; use Neve\Core\Theme_Info; /** * Class Main @@ -315,6 +316,9 @@ public function enqueue() { * @return array */ private function get_localization() { + + $offer = new Limited_Offers(); + $old_about_config = apply_filters( 'ti_about_config_filter', [ 'useful_plugins' => true ] ); $theme_name = apply_filters( 'ti_wl_theme_name', $this->theme_args['name'] ); $plugin_name = apply_filters( 'ti_wl_plugin_name', 'Neve Pro' ); @@ -376,6 +380,7 @@ private function get_localization() { 'getPluginStateBaseURL' => esc_url( rest_url( '/nv/v1/dashboard/plugin-state/' ) ), 'canInstallPlugins' => current_user_can( 'install_plugins' ), 'canActivatePlugins' => current_user_can( 'activate_plugins' ), + 'deal' => $offer->get_localized_data(), ]; if ( defined( 'NEVE_PRO_PATH' ) ) { diff --git a/inc/core/admin.php b/inc/core/admin.php index 4f0338d0db..e24a3779bb 100644 --- a/inc/core/admin.php +++ b/inc/core/admin.php @@ -85,6 +85,11 @@ function () { add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] ); add_filter( 'neve_pro_react_controls_localization', [ $this, 'adapt_conditional_headers' ] ); + + $offer = new Limited_Offers(); + if ( $offer->can_show_dashboard_banner() && $offer->is_active() ) { + $offer->load_dashboard_hooks(); + } } /** diff --git a/inc/core/limited_offers.php b/inc/core/limited_offers.php new file mode 100644 index 0000000000..5fede5d132 --- /dev/null +++ b/inc/core/limited_offers.php @@ -0,0 +1,339 @@ + + * Created on: 17/10/2023 + * + * @package Neve\Core + */ + +namespace Neve\Core; + +use DateTime; +use DateTimeZone; +use Exception; + +/** + * Class LimitedOffers + */ +class Limited_Offers { + + /** + * Active deal. + * + * @var string + */ + private $active = ''; + + /** + * The banner URL. + * + * @var string + */ + public $banner_url = ''; + + /** + * The banner URL for customizer + * + * @var string + */ + public $customizer_banner_url = ''; + + /** + * The key for WP Options to disable the dashboard notification. + * + * @var string + */ + public $wp_option_dismiss_notification_key_base = 'dismiss_themeisle_notice_event_'; + + /** + * LimitedOffers constructor. + */ + public function __construct() { + try { + if ( $this->is_deal_active( 'bf' ) ) { + $this->activate_bff(); + add_filter( 'themeisle_products_deal_priority', [ $this, 'add_priority' ] ); + } + } catch ( Exception $e ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( $e->getMessage() ); // phpcs:ignore + } + } + } + + /** + * Load hooks for the dashboard. + * + * @return void + */ + public function load_dashboard_hooks() { + add_action( 'admin_notices', array( $this, 'render_dashboard_banner' ) ); + add_action( 'wp_ajax_dismiss_themeisle_bf_notice', array( $this, 'disable_notification_ajax' ) ); + } + + /** + * Check if we have an active deal. + * + * @return bool True if the deal is active. + */ + public function is_active() { + return ! empty( $this->active ); + } + + /** + * Activate the Black Friday deal. + * + * @return void + */ + public function activate_bff() { + $this->active = 'bf'; + $this->banner_url = get_template_directory_uri() . '/assets/img/dashboard/black-friday-banner.png'; // TODO: change this based on product. + $this->customizer_banner_url = get_template_directory_uri() . '/assets/img/dashboard/black-friday-customizer-banner.png'; + } + + /** + * Get the slug of the active deal. + * + * @return string Active deal. + */ + public function get_active_deal() { + return $this->active; + } + + /** + * Check if the deal is active with the given slug. + * + * @param string $slug Slug of the deal. + * + * @throws Exception When date is invalid. + */ + public function is_deal_active( $slug ) { + + if ( empty( $slug ) ) { + return false; + } + + if ( 'bf' === $slug ) { + $start_date = '2023-10-10 00:00:00'; // TODO: Add the correct date after QA. + $end_date = '2023-11-27 23:59:00'; + } else { + return false; + } + + return $this->check_date_range( $start_date, $end_date ); + } + + /** + * Get the remaining time for the deal in a human readable format. + * + * @param string $slug Slug of the deal. + * @return string Remaining time for the deal. + */ + public function get_remaining_time_for_deal( $slug ) { + if ( empty( $slug ) ) { + return ''; + } + + if ( 'bf' === $slug ) { + $end_date = '2023-11-27 23:59:00'; + } else { + return ''; + } + + try { + $end_date = new DateTime( $end_date, new DateTimeZone( 'GMT' ) ); + $current_date = new DateTime( 'now', new DateTimeZone( 'GMT' ) ); + $diff = $end_date->diff( $current_date ); + + if ( $diff->days > 0 ) { + return $diff->format( '%a days' ); + } + + if ( $diff->h > 0 ) { + return $diff->format( '%h hours' ); + } + + if ( $diff->i > 0 ) { + return $diff->format( '%i minutes' ); + } + + return $diff->format( '%s seconds' ); + } catch ( Exception $e ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( $e->getMessage() ); // phpcs:ignore + } + } + + return ''; + } + + /** + * Check if the current date is in the range of the offer. + * + * @param string $start Start date. + * @param string $end End date. + * + * @throws Exception When date is invalid. + */ + public function check_date_range( $start, $end ) { + + $start_date = new DateTime( $start, new DateTimeZone( 'GMT' ) ); + $end_date = new DateTime( $end, new DateTimeZone( 'GMT' ) ); + $current_date = new DateTime( 'now', new DateTimeZone( 'GMT' ) ); + + return $start_date <= $current_date && $current_date <= $end_date; + } + + /** + * Get the localized data for the plugin. + * + * @return array Localized data. + */ + public function get_localized_data() { + return array( + 'active' => $this->is_active(), + 'dealSlug' => $this->get_active_deal(), + 'remainingTime' => $this->get_remaining_time_for_deal( $this->get_active_deal() ), + 'urgencyText' => 'Hurry Up! Only ' . $this->get_remaining_time_for_deal( $this->get_active_deal() ) . ' left', + 'bannerUrl' => $this->banner_url, + 'customizerBannerUrl' => $this->customizer_banner_url, + 'linkDashboard' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'dashboard' ), // TODO: change this based on product. + 'linkGlobal' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'globalnotice' ), + 'linkCustomizer' => tsdk_utmify( 'https://themeisle.com/themes/neve/', 'blackfriday23', 'customizer' ), + ); + } + + /** + * Disable the notification via ajax. + * + * @return void + */ + public function disable_notification_ajax() { + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), 'dismiss_themeisle_bf_notice' ) ) { + wp_die( esc_html( __( 'Invalid nonce! Refresh the page and try again.', 'neve' ) ) ); + } + + // We record the time and the plugin of the dismissed notification. + update_option( $this->wp_option_dismiss_notification_key_base . $this->active, 'neve_' . $this->active . '_' . current_time( 'Y_m_d' ) ); + wp_die( 'success' ); + } + + /** + * Render the dashboard banner. + * + * @return void + */ + public function render_dashboard_banner() { + + $message = 'Neve Black Friday Sale - Save big with a Lifetime License of Neve Agency Plan. Only 100 licenses, for a limited time!'; + + ?> + + + + wp_option_dismiss_notification_key_base . $this->active, false ) && $this->has_priority(); + } + + /** + * Add priority to the filter. + * + * @param array $products Registered products. + * @return array Array enhanced with Neve priority. + */ + public function add_priority( $products ) { + if ( ! is_array( $products ) ) { + return [ 'neve' => 0 ]; + } + + $priority['neve'] = 0; // TODO: change this based on product. + + return $priority; + } + + /** + * Check if the current product has priority. + * + * @return bool True if the current product has priority. + */ + public function has_priority() { + $products = apply_filters( 'themeisle_products_deal_priority', [] ); + + if ( empty( $products ) ) { + return true; + } + + $highest_priority = array_search( max( $products ), $products ); + return 'neve' === $highest_priority; // TODO: change this based on product. + } +} diff --git a/inc/customizer/loader.php b/inc/customizer/loader.php index e5b7b9624d..c0e25434da 100644 --- a/inc/customizer/loader.php +++ b/inc/customizer/loader.php @@ -10,6 +10,7 @@ use HFG\Core\Components\Utility\SearchIconButton; use Neve\Core\Factory; +use Neve\Core\Limited_Offers; use Neve\Core\Settings\Config; use Neve\Customizer\Options\Colors_Background; @@ -112,6 +113,7 @@ public function enqueue_customizer_controls() { true ); + $offer = new Limited_Offers(); $bundle_path = get_template_directory_uri() . '/assets/apps/customizer-controls/build/'; $dependencies = ( include get_template_directory() . '/assets/apps/customizer-controls/build/controls.asset.php' ); wp_register_script( 'react-controls', $bundle_path . 'controls.js', $dependencies['dependencies'], $dependencies['version'], true ); @@ -150,6 +152,7 @@ public function enqueue_customizer_controls() { 'customIconKey' => SearchIconButton::CUSTOM_ICON, ], ], + 'deal' => $offer->get_localized_data(), ) ) ); From 13ce62c13d9c3bb929ec4a70ab4cb81257bde4c2 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Tue, 17 Oct 2023 19:17:49 +0300 Subject: [PATCH 02/13] chore: improve BF deal --- .../customizer-controls/src/@types/utils.d.ts | 4 +- .../src/builder-upsell/Upsells.tsx | 14 +++- assets/apps/dashboard/src/Components/App.js | 8 +- assets/apps/dashboard/src/Components/Deal.js | 14 ++-- inc/core/limited_offers.php | 82 +++++++++---------- 5 files changed, 64 insertions(+), 58 deletions(-) diff --git a/assets/apps/customizer-controls/src/@types/utils.d.ts b/assets/apps/customizer-controls/src/@types/utils.d.ts index 8f06aedffb..37b02ae15e 100644 --- a/assets/apps/customizer-controls/src/@types/utils.d.ts +++ b/assets/apps/customizer-controls/src/@types/utils.d.ts @@ -124,7 +124,9 @@ declare global { linkDashboard?: string; linkGlobal?: string; linkCustomizer?: string; - } + customizerBannerAlt?: string; + bannerAlt?: string; + }; }; NeveProReactCustomize: undefined | StringObjectKeys; } diff --git a/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx b/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx index 3b7676564b..b1a1590211 100644 --- a/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx +++ b/assets/apps/customizer-controls/src/builder-upsell/Upsells.tsx @@ -11,7 +11,7 @@ const Upsells: React.FC = ({ control }) => { const { params } = control; const { title, url } = params; - if ( window?.NeveReactCustomize?.deal?.active ) { + if (window?.NeveReactCustomize?.deal?.active) { return ( - ) + ); } return ( diff --git a/assets/apps/dashboard/src/Components/App.js b/assets/apps/dashboard/src/Components/App.js index eb9983e649..846a7d54fe 100644 --- a/assets/apps/dashboard/src/Components/App.js +++ b/assets/apps/dashboard/src/Components/App.js @@ -9,7 +9,7 @@ import { fetchOptions } from '../utils/rest'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { useState, Fragment, useEffect } from '@wordpress/element'; -import Deal from "./Deal"; +import Deal from './Deal'; const App = ({ setSettings, toast, currentTab, setTab }) => { const [loading, setLoading] = useState(true); @@ -28,11 +28,7 @@ const App = ({ setSettings, toast, currentTab, setTab }) => {
- { - ( 'start' === currentTab ) && ( - - ) - } + {'start' === currentTab && } {'starter-sites' !== currentTab && }
diff --git a/assets/apps/dashboard/src/Components/Deal.js b/assets/apps/dashboard/src/Components/Deal.js index 4540afb5ad..b60d62128b 100644 --- a/assets/apps/dashboard/src/Components/Deal.js +++ b/assets/apps/dashboard/src/Components/Deal.js @@ -1,17 +1,21 @@ -const Deal = () => { +/* global neveDash */ - if ( ! Boolean(window.neveDash?.deal?.active)) { +const Deal = () => { + if (!Boolean(window.neveDash?.deal?.active)) { return <>; } return ( - ) -} + ); +}; export default Deal; diff --git a/inc/core/limited_offers.php b/inc/core/limited_offers.php index 5fede5d132..b337bd7068 100644 --- a/inc/core/limited_offers.php +++ b/inc/core/limited_offers.php @@ -27,25 +27,18 @@ class Limited_Offers { private $active = ''; /** - * The banner URL. - * - * @var string - */ - public $banner_url = ''; - - /** - * The banner URL for customizer + * The key for WP Options to disable the dashboard notification. * * @var string */ - public $customizer_banner_url = ''; + public $wp_option_dismiss_notification_key_base = 'dismiss_themeisle_notice_event_'; /** - * The key for WP Options to disable the dashboard notification. + * Offer Links * - * @var string + * @var array */ - public $wp_option_dismiss_notification_key_base = 'dismiss_themeisle_notice_event_'; + public $offer_metadata = array(); /** * LimitedOffers constructor. @@ -54,7 +47,6 @@ public function __construct() { try { if ( $this->is_deal_active( 'bf' ) ) { $this->activate_bff(); - add_filter( 'themeisle_products_deal_priority', [ $this, 'add_priority' ] ); } } catch ( Exception $e ) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { @@ -69,8 +61,9 @@ public function __construct() { * @return void */ public function load_dashboard_hooks() { + add_filter( 'themeisle_products_deal_priority', array( $this, 'add_priority' ) ); add_action( 'admin_notices', array( $this, 'render_dashboard_banner' ) ); - add_action( 'wp_ajax_dismiss_themeisle_bf_notice', array( $this, 'disable_notification_ajax' ) ); + add_action( 'wp_ajax_dismiss_themeisle_event_notice_neve', array( $this, 'disable_notification_ajax' ) ); } /** @@ -88,9 +81,17 @@ public function is_active() { * @return void */ public function activate_bff() { - $this->active = 'bf'; - $this->banner_url = get_template_directory_uri() . '/assets/img/dashboard/black-friday-banner.png'; // TODO: change this based on product. - $this->customizer_banner_url = get_template_directory_uri() . '/assets/img/dashboard/black-friday-customizer-banner.png'; + $this->active = 'bf'; + + $this->offer_metadata = array( + 'bannerUrl' => get_template_directory_uri() . '/assets/img/dashboard/black-friday-banner.png', + 'bannerAlt' => 'Neve Black Friday Sale', + 'customizerBannerUrl' => get_template_directory_uri() . '/assets/img/dashboard/black-friday-customizer-banner.png', + 'customizerBannerAlt' => 'Neve Black Friday Sale', + 'linkDashboard' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'dashboard' ), // TODO: change this based on product. + 'linkGlobal' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'globalnotice' ), + 'linkCustomizer' => tsdk_utmify( 'https://themeisle.com/themes/neve/', 'blackfriday23', 'customizer' ), + ); } /** @@ -192,16 +193,14 @@ public function check_date_range( $start, $end ) { * @return array Localized data. */ public function get_localized_data() { - return array( - 'active' => $this->is_active(), - 'dealSlug' => $this->get_active_deal(), - 'remainingTime' => $this->get_remaining_time_for_deal( $this->get_active_deal() ), - 'urgencyText' => 'Hurry Up! Only ' . $this->get_remaining_time_for_deal( $this->get_active_deal() ) . ' left', - 'bannerUrl' => $this->banner_url, - 'customizerBannerUrl' => $this->customizer_banner_url, - 'linkDashboard' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'dashboard' ), // TODO: change this based on product. - 'linkGlobal' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'globalnotice' ), - 'linkCustomizer' => tsdk_utmify( 'https://themeisle.com/themes/neve/', 'blackfriday23', 'customizer' ), + return array_merge( + array( + 'active' => $this->is_active(), + 'dealSlug' => $this->get_active_deal(), + 'remainingTime' => $this->get_remaining_time_for_deal( $this->get_active_deal() ), + 'urgencyText' => 'Hurry Up! Only ' . $this->get_remaining_time_for_deal( $this->get_active_deal() ) . ' left', + ), + $this->offer_metadata ); } @@ -211,8 +210,8 @@ public function get_localized_data() { * @return void */ public function disable_notification_ajax() { - if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), 'dismiss_themeisle_bf_notice' ) ) { - wp_die( esc_html( __( 'Invalid nonce! Refresh the page and try again.', 'neve' ) ) ); + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), 'dismiss_themeisle_event_notice_neve' ) ) { + wp_die( 'Invalid nonce! Refresh the page and try again.' ); } // We record the time and the plugin of the dismissed notification. @@ -227,6 +226,10 @@ public function disable_notification_ajax() { */ public function render_dashboard_banner() { + if ( ! $this->has_priority() ) { + return; + } + $message = 'Neve Black Friday Sale - Save big with a Lifetime License of Neve Agency Plan. Only 100 licenses, for a limited time!'; ?> @@ -257,8 +260,8 @@ public function render_dashboard_banner() { - - + +
@@ -273,8 +276,8 @@ public function render_dashboard_banner() { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ - action: 'dismiss_themeisle_bf_notice', - nonce: '' + action: 'dismiss_themeisle_event_notice_neve', + nonce: '' }) }) .then(response => response.text()) @@ -302,7 +305,7 @@ public function render_dashboard_banner() { * @return bool */ public function can_show_dashboard_banner() { - return ! get_option( $this->wp_option_dismiss_notification_key_base . $this->active, false ) && $this->has_priority(); + return ! get_option( $this->wp_option_dismiss_notification_key_base . $this->active, false ); } /** @@ -312,13 +315,8 @@ public function can_show_dashboard_banner() { * @return array Array enhanced with Neve priority. */ public function add_priority( $products ) { - if ( ! is_array( $products ) ) { - return [ 'neve' => 0 ]; - } - - $priority['neve'] = 0; // TODO: change this based on product. - - return $priority; + $products['neve'] = 0; // TODO: change this based on product. + return $products; } /** @@ -333,7 +331,7 @@ public function has_priority() { return true; } - $highest_priority = array_search( max( $products ), $products ); + $highest_priority = array_search( min( $products ), $products ); return 'neve' === $highest_priority; // TODO: change this based on product. } } From 6483ef067db42d0bd1a25507b3ad22dab59af514 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Wed, 18 Oct 2023 10:10:45 +0300 Subject: [PATCH 03/13] chore: clean up --- inc/core/limited_offers.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inc/core/limited_offers.php b/inc/core/limited_offers.php index b337bd7068..f56b6d6d21 100644 --- a/inc/core/limited_offers.php +++ b/inc/core/limited_offers.php @@ -88,7 +88,7 @@ public function activate_bff() { 'bannerAlt' => 'Neve Black Friday Sale', 'customizerBannerUrl' => get_template_directory_uri() . '/assets/img/dashboard/black-friday-customizer-banner.png', 'customizerBannerAlt' => 'Neve Black Friday Sale', - 'linkDashboard' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'dashboard' ), // TODO: change this based on product. + 'linkDashboard' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'dashboard' ), 'linkGlobal' => tsdk_utmify( 'https://themeisle.com/themes/neve/blackfriday', 'blackfridayltd23', 'globalnotice' ), 'linkCustomizer' => tsdk_utmify( 'https://themeisle.com/themes/neve/', 'blackfriday23', 'customizer' ), ); @@ -252,7 +252,6 @@ public function render_dashboard_banner() {
- @@ -309,18 +308,19 @@ public function can_show_dashboard_banner() { } /** - * Add priority to the filter. + * Add product priority to the filter. * * @param array $products Registered products. * @return array Array enhanced with Neve priority. */ public function add_priority( $products ) { - $products['neve'] = 0; // TODO: change this based on product. + $products['neve'] = 0; return $products; } /** * Check if the current product has priority. + * Use this for conditional rendering if you want to show the banner only for one product. * * @return bool True if the current product has priority. */ @@ -332,6 +332,6 @@ public function has_priority() { } $highest_priority = array_search( min( $products ), $products ); - return 'neve' === $highest_priority; // TODO: change this based on product. + return 'neve' === $highest_priority; } } From db48daaed77d0869ca87ee34cae919e077277a7b Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Wed, 18 Oct 2023 10:54:11 +0300 Subject: [PATCH 04/13] chore: use timelines --- inc/core/limited_offers.php | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/inc/core/limited_offers.php b/inc/core/limited_offers.php index f56b6d6d21..be2bb2ea1c 100644 --- a/inc/core/limited_offers.php +++ b/inc/core/limited_offers.php @@ -40,6 +40,18 @@ class Limited_Offers { */ public $offer_metadata = array(); + /** + * Timeline for the offers. + * + * @var array[] + */ + public $timelines = array( + 'bf' => array( + 'start' => '2023-10-10 00:00:00', + 'end' => '2023-11-27 23:59:00', + ), // TODO: Add the correct date. + ); + /** * LimitedOffers constructor. */ @@ -112,18 +124,11 @@ public function get_active_deal() { */ public function is_deal_active( $slug ) { - if ( empty( $slug ) ) { - return false; - } - - if ( 'bf' === $slug ) { - $start_date = '2023-10-10 00:00:00'; // TODO: Add the correct date after QA. - $end_date = '2023-11-27 23:59:00'; - } else { + if ( empty( $slug ) || ! array_key_exists( $slug, $this->timelines ) ) { return false; } - return $this->check_date_range( $start_date, $end_date ); + return $this->check_date_range( $this->timelines[ $slug ]['start'], $this->timelines[ $slug ]['end'] ); } /** @@ -133,18 +138,12 @@ public function is_deal_active( $slug ) { * @return string Remaining time for the deal. */ public function get_remaining_time_for_deal( $slug ) { - if ( empty( $slug ) ) { - return ''; - } - - if ( 'bf' === $slug ) { - $end_date = '2023-11-27 23:59:00'; - } else { + if ( empty( $slug ) || ! array_key_exists( $slug, $this->timelines ) ) { return ''; } try { - $end_date = new DateTime( $end_date, new DateTimeZone( 'GMT' ) ); + $end_date = new DateTime( $this->timelines[ $slug ]['end'], new DateTimeZone( 'GMT' ) ); $current_date = new DateTime( 'now', new DateTimeZone( 'GMT' ) ); $diff = $end_date->diff( $current_date ); From 4e94ee9b8019aec821da78fa805e8f71ac6050f5 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Wed, 18 Oct 2023 14:36:53 +0300 Subject: [PATCH 05/13] chore: enable sale for all tabs --- assets/apps/dashboard/src/Components/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/apps/dashboard/src/Components/App.js b/assets/apps/dashboard/src/Components/App.js index 846a7d54fe..1e356e1da9 100644 --- a/assets/apps/dashboard/src/Components/App.js +++ b/assets/apps/dashboard/src/Components/App.js @@ -28,7 +28,7 @@ const App = ({ setSettings, toast, currentTab, setTab }) => {
- {'start' === currentTab && } + {'starter-sites' !== currentTab && }
From dab1779cd23e1fecd9dddb8352f4bd270565444a Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Wed, 18 Oct 2023 18:18:21 +0300 Subject: [PATCH 06/13] chore: response banner --- .../dashboard/src/scss/content/_start.scss | 25 ++++++++++++++++--- inc/core/limited_offers.php | 10 ++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/assets/apps/dashboard/src/scss/content/_start.scss b/assets/apps/dashboard/src/scss/content/_start.scss index ef3321a6aa..33a7b68ce3 100644 --- a/assets/apps/dashboard/src/scss/content/_start.scss +++ b/assets/apps/dashboard/src/scss/content/_start.scss @@ -49,7 +49,6 @@ } } -@import url('https://fonts.cdnfonts.com/css/barlow'); .nv-deal { margin-bottom: 10px; display: flex; @@ -58,13 +57,18 @@ position: relative; } + img { + width: 100%; + } + .nv-urgency { position: absolute; - top: 15px; - left: 19px; + + top: 10%; + left: 2.7%; color: #FFF; - font-family: Barlow, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", sans-serif; + font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", sans-serif; font-size: 14px; font-style: normal; font-weight: 700; @@ -73,3 +77,16 @@ text-transform: uppercase; } } + +@media(max-width: 480px) { + .nv-deal .nv-urgency { + font-size: 7px; + } +} + +@media (min-width: 481px) and (max-width: 1024px) { + .nv-deal .nv-urgency { + font-size: 10px; + } +} + diff --git a/inc/core/limited_offers.php b/inc/core/limited_offers.php index be2bb2ea1c..ef6b5e2383 100644 --- a/inc/core/limited_offers.php +++ b/inc/core/limited_offers.php @@ -74,7 +74,7 @@ public function __construct() { */ public function load_dashboard_hooks() { add_filter( 'themeisle_products_deal_priority', array( $this, 'add_priority' ) ); - add_action( 'admin_notices', array( $this, 'render_dashboard_banner' ) ); + add_action( 'admin_notices', array( $this, 'render_notice' ) ); add_action( 'wp_ajax_dismiss_themeisle_event_notice_neve', array( $this, 'disable_notification_ajax' ) ); } @@ -223,7 +223,7 @@ public function disable_notification_ajax() { * * @return void */ - public function render_dashboard_banner() { + public function render_notice() { if ( ! $this->has_priority() ) { return; @@ -257,10 +257,10 @@ public function render_dashboard_banner() { + + Learn more + - - -