content = $content; } public static function getCmsName(): string { return 'Hero Section'; } public static function getCmsDescription(): string { return 'Large header section with headline, text and optional background image with call-to-action button'; } public static function getCmsCategory(): string { return 'Layout'; } public static function getCmsIcon(): string { return 'hero'; } public static function getCmsTags(): array { return ['header', 'hero', 'banner', 'cta']; } public static function getCmsPreview(): string { return '

Hero Headline

Compelling subtitle text that draws attention

'; } public static function getCmsFields(): array { return [ TextField::make('headline', 'Headline') ->translatable() ->required() ->maxLength(100) ->helpText('Main headline for the hero section'), TextField::make('subheadline', 'Subheadline') ->translatable() ->maxLength(200) ->helpText('Supporting text below the main headline'), WysiwygField::make('description', 'Description') ->translatable() ->basic() ->helpText('Additional descriptive text'), TextField::make('cta_text', 'Button Text') ->translatable() ->maxLength(50) ->placeholder('Get Started'), TextField::make('cta_link', 'Button Link') ->url() ->placeholder('https://example.com'), BooleanField::make('cta_new_tab', 'Open Link in New Tab') ->default(false), MediaField::make('background_image', 'Background Image') ->images() ->helpText('Optional background image for the hero section'), BooleanField::make('dark_overlay', 'Dark Overlay') ->default(true) ->helpText('Add dark overlay for better text readability'), TextField::make('text_alignment', 'Text Alignment') ->default('center') ->helpText('Text alignment: left, center, right'), TextField::make('min_height', 'Minimum Height') ->default('500px') ->helpText('Minimum height of the hero section (e.g., 500px, 50vh)'), ]; } public static function validateContent(array $content): array { $errors = []; // Custom validation: If CTA text is provided, link must also be provided $ctaText = $content['cta_text'] ?? []; $ctaLink = $content['cta_link'] ?? ''; foreach ($ctaText as $locale => $text) { if (! empty($text) && empty($ctaLink)) { $errors['cta_link'] = ['Button link is required when button text is provided']; break; } } return $errors; } public function render() { return view('flux-cms-starter::components.hero-section'); } // Helper methods for accessing content protected function getHeadline(?string $locale = null): string { $locale = $locale ?? app()->getLocale(); return $this->content['headline'][$locale] ?? ''; } protected function getSubheadline(?string $locale = null): string { $locale = $locale ?? app()->getLocale(); return $this->content['subheadline'][$locale] ?? ''; } protected function getDescription(?string $locale = null): string { $locale = $locale ?? app()->getLocale(); return $this->content['description'][$locale] ?? ''; } protected function getCtaText(?string $locale = null): string { $locale = $locale ?? app()->getLocale(); return $this->content['cta_text'][$locale] ?? ''; } protected function getCtaLink(): string { return $this->content['cta_link'] ?? ''; } protected function getTextAlignment(): string { return $this->content['text_alignment'] ?? 'center'; } protected function getMinHeight(): string { return $this->content['min_height'] ?? '500px'; } protected function hasCta(): bool { return ! empty($this->getCtaText()) && ! empty($this->getCtaLink()); } protected function hasBackgroundImage(): bool { return ! empty($this->content['background_image']); } protected function getBackgroundImageUrl(): ?string { if (! $this->hasBackgroundImage()) { return null; } $mediaId = $this->content['background_image']; $media = \Spatie\MediaLibrary\MediaCollections\Models\Media::find($mediaId); return $media?->getUrl('large') ?? $media?->getUrl(); } protected function hasDarkOverlay(): bool { return $this->content['dark_overlay'] ?? true; } protected function opensInNewTab(): bool { return $this->content['cta_new_tab'] ?? false; } protected function getContainerClasses(): string { $classes = ['hero-section', 'relative', 'flex', 'items-center', 'justify-center']; // Text alignment $alignment = $this->getTextAlignment(); if ($alignment === 'left') { $classes[] = 'text-left'; } elseif ($alignment === 'right') { $classes[] = 'text-right'; } else { $classes[] = 'text-center'; } return implode(' ', $classes); } protected function getTextClasses(): string { $classes = ['relative', 'z-10']; if ($this->hasBackgroundImage()) { $classes[] = 'text-white'; } return implode(' ', $classes); } }