Files
cannaiq/wordpress-plugin/widgets/card-template-promo-banner.php
Kelly 0b4ed48d2f
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
feat: Add premade card templates and click analytics
WordPress Plugin v2.0.0:
- Add Promo Banner widget (dark banner with deal text)
- Add Horizontal Product Row widget (wide list format)
- Add Category Card widget (image-based categories)
- Add Compact Card widget (dense grid layout)
- Add CannaiQAnalytics click tracking (tracks add_to_cart,
  product_view, promo_click, category_click events)
- Register cannaiq-templates Elementor category
- Fix branding: CannaiQAnalytics (not CannaIQAnalytics)

Backend:
- Add POST /api/analytics/click endpoint for WordPress plugin
- Accepts API token auth, records to product_click_events table
- Stores metadata: product_name, price, category, url, referrer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 02:03:28 -07:00

277 lines
8.6 KiB
PHP

<?php
/**
* Elementor Promo Banner Widget
* Dark banner with deal text, product image, and shop button
*/
if (!defined('ABSPATH')) {
exit;
}
class CannaIQ_Promo_Banner_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'cannaiq_promo_banner';
}
public function get_title() {
return __('CannaiQ Promo Banner', 'cannaiq-menus');
}
public function get_icon() {
return 'eicon-banner';
}
public function get_categories() {
return ['cannaiq-templates'];
}
public function get_keywords() {
return ['cannaiq', 'promo', 'banner', 'deal', 'special'];
}
protected function register_controls() {
// Content Section
$this->start_controls_section(
'content_section',
[
'label' => __('Content', 'cannaiq-menus'),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'headline',
[
'label' => __('Headline', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => '2 for $35 | Eighth Flower (3.5g)',
'placeholder' => __('Deal headline...', 'cannaiq-menus'),
'label_block' => true,
]
);
$this->add_control(
'subtext',
[
'label' => __('Subtext', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => 'Lost Dutchmen ($20)',
'placeholder' => __('Optional subtext...', 'cannaiq-menus'),
'label_block' => true,
]
);
$this->add_control(
'image',
[
'label' => __('Product Image', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::MEDIA,
'default' => [
'url' => '',
],
]
);
$this->add_control(
'button_text',
[
'label' => __('Button Text', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => 'SHOP',
]
);
$this->add_control(
'button_url',
[
'label' => __('Button URL', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::URL,
'placeholder' => __('https://...', 'cannaiq-menus'),
'default' => [
'url' => '#',
],
]
);
$this->end_controls_section();
// Style Section
$this->start_controls_section(
'style_section',
[
'label' => __('Style', 'cannaiq-menus'),
'tab' => \Elementor\Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'background_color',
[
'label' => __('Background Color', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#1a1a2e',
]
);
$this->add_control(
'text_color',
[
'label' => __('Text Color', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#ffffff',
]
);
$this->add_control(
'button_bg_color',
[
'label' => __('Button Background', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#22c55e',
]
);
$this->add_control(
'button_text_color',
[
'label' => __('Button Text Color', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#ffffff',
]
);
$this->add_control(
'border_radius',
[
'label' => __('Border Radius', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 30,
],
],
'default' => [
'size' => 12,
],
]
);
$this->add_control(
'show_watermark',
[
'label' => __('Show Watermark Pattern', 'cannaiq-menus'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Yes', 'cannaiq-menus'),
'label_off' => __('No', 'cannaiq-menus'),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
$bg_color = $settings['background_color'];
$text_color = $settings['text_color'];
$btn_bg = $settings['button_bg_color'];
$btn_text = $settings['button_text_color'];
$radius = $settings['border_radius']['size'] . 'px';
$show_watermark = $settings['show_watermark'] === 'yes';
$url = $settings['button_url']['url'] ?? '#';
$target = !empty($settings['button_url']['is_external']) ? '_blank' : '_self';
?>
<div class="cannaiq-promo-banner" style="
background-color: <?php echo esc_attr($bg_color); ?>;
color: <?php echo esc_attr($text_color); ?>;
border-radius: <?php echo esc_attr($radius); ?>;
padding: 24px 32px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
position: relative;
overflow: hidden;
">
<?php if ($show_watermark): ?>
<div class="cannaiq-promo-watermark" style="
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.05;
font-size: 48px;
font-weight: bold;
letter-spacing: 8px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
pointer-events: none;
overflow: hidden;
">
<?php for ($i = 0; $i < 8; $i++): ?>
<span style="margin: 8px 16px;">DEAL</span>
<?php endfor; ?>
</div>
<?php endif; ?>
<div class="cannaiq-promo-content" style="position: relative; z-index: 1; flex: 1;">
<div class="cannaiq-promo-headline" style="
font-size: 18px;
font-weight: 600;
margin-bottom: 12px;
line-height: 1.3;
">
<?php echo esc_html($settings['headline']); ?>
<?php if (!empty($settings['subtext'])): ?>
<br><?php echo esc_html($settings['subtext']); ?>
<?php endif; ?>
</div>
<a href="<?php echo esc_url($url); ?>"
target="<?php echo esc_attr($target); ?>"
class="cannaiq-promo-button"
style="
display: inline-block;
background-color: <?php echo esc_attr($btn_bg); ?>;
color: <?php echo esc_attr($btn_text); ?>;
padding: 10px 24px;
border-radius: 6px;
text-decoration: none;
font-weight: 600;
font-size: 14px;
transition: opacity 0.2s;
">
<?php echo esc_html($settings['button_text']); ?>
</a>
</div>
<?php if (!empty($settings['image']['url'])): ?>
<div class="cannaiq-promo-image" style="
position: relative;
z-index: 1;
flex-shrink: 0;
">
<img src="<?php echo esc_url($settings['image']['url']); ?>"
alt="<?php echo esc_attr($settings['headline']); ?>"
style="
max-height: 100px;
width: auto;
object-fit: contain;
" />
</div>
<?php endif; ?>
</div>
<?php
}
}