Campo whatsapp_message editável por modalidade (Filament) com fallback para template padrão. Cards da home, faixa 'Conversar com a Amare' e CTA final da página de detalhe abrem o WhatsApp diretamente quando número configurado, mantendo briefing como fallback.
198 lines
9.2 KiB
PHP
198 lines
9.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Resources\WeddingPackages\Schemas;
|
|
|
|
use App\Domain\Marketing\PackageIconCatalog;
|
|
use App\Support\PublicImageUploadRules;
|
|
use Filament\Forms\Components\DateTimePicker;
|
|
use Filament\Forms\Components\Repeater;
|
|
use Filament\Forms\Components\Select;
|
|
use Filament\Forms\Components\Textarea;
|
|
use Filament\Forms\Components\TextInput;
|
|
use Filament\Schemas\Components\Section;
|
|
use Filament\Schemas\Schema;
|
|
|
|
class WeddingPackageForm
|
|
{
|
|
public static function configure(Schema $schema): Schema
|
|
{
|
|
return $schema
|
|
->components([
|
|
Section::make('Identificação')
|
|
->schema([
|
|
TextInput::make('name')
|
|
->label('Nome da modalidade')
|
|
->required()
|
|
->maxLength(255)
|
|
->live(onBlur: true)
|
|
->afterStateUpdated(function (?string $state, callable $set, callable $get): void {
|
|
if (blank($get('slug'))) {
|
|
$set('slug', str($state)->slug()->toString());
|
|
}
|
|
}),
|
|
TextInput::make('slug')
|
|
->label('Slug')
|
|
->required()
|
|
->maxLength(255)
|
|
->unique(ignoreRecord: true),
|
|
TextInput::make('level')
|
|
->label('Número / tipo (ex.: 01 / COMPLETA)')
|
|
->required()
|
|
->maxLength(255),
|
|
TextInput::make('tag')
|
|
->label('Etiqueta curta (ex.: Assessoria completa)')
|
|
->maxLength(255),
|
|
TextInput::make('subtitle')
|
|
->label('Frase de apoio')
|
|
->maxLength(255),
|
|
Textarea::make('summary')
|
|
->label('Resumo')
|
|
->required()
|
|
->rows(4),
|
|
Repeater::make('scope_items')
|
|
->label('O que está incluído')
|
|
->schema([
|
|
TextInput::make('item')
|
|
->label('Item')
|
|
->required()
|
|
->maxLength(255),
|
|
])
|
|
->defaultItems(4)
|
|
->minItems(1)
|
|
->addActionLabel('Adicionar item')
|
|
->required(),
|
|
TextInput::make('cta_label')
|
|
->label('Texto do botão')
|
|
->required()
|
|
->maxLength(255),
|
|
Textarea::make('whatsapp_message')
|
|
->label('Mensagem do WhatsApp (deixe vazio para usar o padrão)')
|
|
->helperText('Texto enviado ao cliente ao tocar no botão de contato. O nome da modalidade é citado automaticamente se vazio.')
|
|
->rows(3),
|
|
TextInput::make('compare_heading')
|
|
->label('Comparação — título (leitura rápida)')
|
|
->maxLength(255),
|
|
TextInput::make('compare_summary')
|
|
->label('Comparação — resumo (leitura rápida)')
|
|
->maxLength(255),
|
|
TextInput::make('sort_order')
|
|
->label('Ordem')
|
|
->numeric()
|
|
->default(0)
|
|
->required(),
|
|
DateTimePicker::make('published_at')
|
|
->label('Publicado em')
|
|
->seconds(false),
|
|
])
|
|
->columns(2),
|
|
Section::make('Hero da página')
|
|
->description('Dados de abertura da página da modalidade.')
|
|
->schema([
|
|
TextInput::make('eyebrow')
|
|
->label('Eyebrow (ex.: Assessoria)')
|
|
->maxLength(255),
|
|
TextInput::make('title_line')
|
|
->label('Título (linha principal)')
|
|
->maxLength(255),
|
|
TextInput::make('title_emphasis')
|
|
->label('Título (ênfase em itálico)')
|
|
->maxLength(255),
|
|
Textarea::make('hero_lead')
|
|
->label('Texto de abertura')
|
|
->rows(3),
|
|
PublicImageUploadRules::fileUpload('hero_image_path', 'Imagem do hero'),
|
|
PublicImageUploadRules::altTextField('hero_image_alt', 'hero_image_path'),
|
|
])
|
|
->columns(2),
|
|
Section::make('Diferenciais')
|
|
->description('Faixa escura com os valores da modalidade.')
|
|
->schema([
|
|
Repeater::make('benefits')
|
|
->label('Diferenciais')
|
|
->schema([
|
|
Select::make('icon_key')
|
|
->label('Ícone')
|
|
->options(PackageIconCatalog::labels())
|
|
->required(),
|
|
TextInput::make('label')
|
|
->label('Rótulo')
|
|
->required()
|
|
->maxLength(255),
|
|
])
|
|
->defaultItems(4)
|
|
->minItems(1)
|
|
->addActionLabel('Adicionar diferencial'),
|
|
])
|
|
->columns(1),
|
|
Section::make('O que está incluso')
|
|
->schema([
|
|
Repeater::make('included_items')
|
|
->label('Itens inclusos')
|
|
->schema([
|
|
Select::make('icon_key')
|
|
->label('Ícone')
|
|
->options(PackageIconCatalog::labels())
|
|
->required(),
|
|
TextInput::make('title')
|
|
->label('Título')
|
|
->required()
|
|
->maxLength(255),
|
|
Textarea::make('description')
|
|
->label('Descrição')
|
|
->rows(2)
|
|
->maxLength(500),
|
|
])
|
|
->defaultItems(6)
|
|
->minItems(1)
|
|
->addActionLabel('Adicionar item'),
|
|
])
|
|
->columns(1),
|
|
Section::make('Para quem é este pacote')
|
|
->schema([
|
|
TextInput::make('audience_heading')
|
|
->label('Título da seção')
|
|
->maxLength(255),
|
|
Textarea::make('audience_intro')
|
|
->label('Texto de introdução')
|
|
->rows(3),
|
|
Repeater::make('audience_points')
|
|
->label('Público')
|
|
->schema([
|
|
TextInput::make('point')
|
|
->label('Ponto')
|
|
->required()
|
|
->maxLength(255),
|
|
])
|
|
->defaultItems(4)
|
|
->minItems(1)
|
|
->addActionLabel('Adicionar ponto'),
|
|
PublicImageUploadRules::fileUpload('audience_image_path', 'Imagem da seção'),
|
|
PublicImageUploadRules::altTextField('audience_image_alt', 'audience_image_path'),
|
|
])
|
|
->columns(2),
|
|
Section::make('CTA final')
|
|
->schema([
|
|
TextInput::make('final_cta_heading')
|
|
->label('Título do CTA final')
|
|
->maxLength(255),
|
|
Textarea::make('final_cta_body')
|
|
->label('Texto do CTA final')
|
|
->rows(3),
|
|
])
|
|
->columns(2),
|
|
Section::make('SEO')
|
|
->schema([
|
|
TextInput::make('meta_title')
|
|
->label('Meta title')
|
|
->maxLength(255),
|
|
Textarea::make('meta_description')
|
|
->label('Meta description')
|
|
->rows(3),
|
|
])
|
|
->columns(2),
|
|
]);
|
|
}
|
|
}
|