Files
ui-essentials/projects/ui-landing-pages/src/lib/components/conversion/cta-section.component.ts
skyai_dev 246c62fd49 Add landing pages library with comprehensive components and demos
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-06 13:52:41 +10:00

119 lines
4.7 KiB
TypeScript

import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ButtonComponent, ContainerComponent } from 'ui-essentials';
import { CTASectionConfig } from '../../interfaces/conversion.interfaces';
@Component({
selector: 'ui-cta-section',
standalone: true,
imports: [
CommonModule,
ButtonComponent,
ContainerComponent,
],
template: `
<section
class="cta-section"
[class.cta-section--gradient]="config.backgroundType === 'gradient'"
[class.cta-section--pattern]="config.backgroundType === 'pattern'"
[class.cta-section--image]="config.backgroundType === 'image'"
[class.cta-section--solid]="config.backgroundType === 'solid'">
<ui-container>
<div class="cta-section__content">
<!-- Urgency Indicator -->
<div
*ngIf="config.urgency"
class="cta-section__urgency"
[class.cta-section__urgency--countdown]="config.urgency.type === 'countdown'"
[class.cta-section__urgency--limited]="config.urgency.type === 'limited-offer'"
[class.cta-section__urgency--social]="config.urgency.type === 'social-proof'">
<div *ngIf="config.urgency.type === 'countdown' && config.urgency.endDate" class="countdown">
<div class="countdown__item">
<span class="countdown__value">{{ getTimeRemaining().days }}</span>
<span class="countdown__label">Days</span>
</div>
<div class="countdown__item">
<span class="countdown__value">{{ getTimeRemaining().hours }}</span>
<span class="countdown__label">Hours</span>
</div>
<div class="countdown__item">
<span class="countdown__value">{{ getTimeRemaining().minutes }}</span>
<span class="countdown__label">Minutes</span>
</div>
</div>
<div *ngIf="config.urgency.type === 'limited-offer'" class="limited-offer">
<span class="limited-offer__text">{{ config.urgency.text }}</span>
<span *ngIf="config.urgency.remaining" class="limited-offer__remaining">
Only {{ config.urgency.remaining }} left!
</span>
</div>
<div *ngIf="config.urgency.type === 'social-proof'" class="social-proof">
<span class="social-proof__text">{{ config.urgency.text }}</span>
</div>
</div>
<!-- Main Content -->
<h2 class="cta-section__title">{{ config.title }}</h2>
<p *ngIf="config.description" class="cta-section__description">
{{ config.description }}
</p>
<!-- CTA Buttons -->
<div class="cta-section__actions">
<ui-button
[variant]="config.ctaPrimary.variant || 'filled'"
[size]="config.ctaPrimary.size || 'large'"
[disabled]="config.ctaPrimary.disabled || false"
[loading]="config.ctaPrimary.loading || false"
(click)="config.ctaPrimary.action()"
class="cta-section__button cta-section__button--primary">
{{ config.ctaPrimary.text }}
</ui-button>
<ui-button
*ngIf="config.ctaSecondary"
[variant]="config.ctaSecondary.variant || 'outlined'"
[size]="config.ctaSecondary.size || 'large'"
[disabled]="config.ctaSecondary.disabled || false"
[loading]="config.ctaSecondary.loading || false"
(click)="config.ctaSecondary.action()"
class="cta-section__button cta-section__button--secondary">
{{ config.ctaSecondary.text }}
</ui-button>
</div>
</div>
</ui-container>
</section>
`,
styleUrls: ['./cta-section.component.scss']
})
export class CTASectionComponent {
@Input() config!: CTASectionConfig;
getTimeRemaining(): { days: number; hours: number; minutes: number; seconds: number } {
if (!this.config.urgency?.endDate) {
return { days: 0, hours: 0, minutes: 0, seconds: 0 };
}
const now = new Date().getTime();
const end = this.config.urgency.endDate.getTime();
const difference = end - now;
if (difference > 0) {
return {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),
minutes: Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60)),
seconds: Math.floor((difference % (1000 * 60)) / 1000)
};
}
return { days: 0, hours: 0, minutes: 0, seconds: 0 };
}
}