feat: CTA de orientação das modalidades via WhatsApp
Some checks failed
CI / static (pull_request) Successful in 2m55s
CI / unit (pull_request) Successful in 3m27s
CI / feature (pull_request) Successful in 2m57s
CI / container (pull_request) Successful in 59s
CI / browser (pull_request) Failing after 2m11s

A banda "ainda não sabe" abre wa.me com mensagem de orientação; sem número, cai no briefing.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-13 23:39:29 -03:00
parent 220143390e
commit 9ee9b51b0c
5 changed files with 49 additions and 9 deletions

View File

@@ -8,20 +8,44 @@ use App\Models\SiteSetting;
final class PackageContactLink final class PackageContactLink
{ {
public const GUIDANCE_MESSAGE = 'Olá, ainda não sei qual modalidade de assessoria faz sentido para o meu casamento e gostaria de orientação.';
/** /**
* Resolve the contextual contact link for a wedding package modality. * Resolve the contextual contact link for a wedding package modality.
* *
* @return array{href: string, isWhatsapp: bool} * @return array{href: string, isWhatsapp: bool}
*/ */
public static function for(SiteSetting $settings, string $packageName): array public static function for(SiteSetting $settings, string $packageName): array
{
return self::resolve(
$settings,
'Olá, gostaria de conversar sobre a modalidade '.$packageName.' para meu casamento.',
route('briefing', ['servico_interesse' => $packageName]),
);
}
/**
* WhatsApp (or briefing fallback) when the visitor does not know which modality to choose.
*
* @return array{href: string, isWhatsapp: bool}
*/
public static function forGuidance(SiteSetting $settings): array
{
return self::resolve($settings, self::GUIDANCE_MESSAGE, route('briefing'));
}
/**
* @return array{href: string, isWhatsapp: bool}
*/
private static function resolve(SiteSetting $settings, string $whatsappMessage, string $fallbackHref): array
{ {
$digits = preg_replace('/\D/', '', (string) $settings->whatsapp_number); $digits = preg_replace('/\D/', '', (string) $settings->whatsapp_number);
$isWhatsapp = strlen($digits) >= 10; $isWhatsapp = strlen($digits) >= 10;
return [ return [
'href' => $isWhatsapp 'href' => $isWhatsapp
? 'https://wa.me/'.$digits.'?text='.rawurlencode('Olá, gostaria de conversar sobre a modalidade '.$packageName.' para meu casamento.') ? 'https://wa.me/'.$digits.'?text='.rawurlencode($whatsappMessage)
: route('briefing', ['servico_interesse' => $packageName]), : $fallbackHref,
'isWhatsapp' => $isWhatsapp, 'isWhatsapp' => $isWhatsapp,
]; ];
} }

View File

@@ -14,9 +14,6 @@
'note' => 'Nomenclaturas exibidas conforme materiais/reunião; confirmar versão final antes da publicação.', 'note' => 'Nomenclaturas exibidas conforme materiais/reunião; confirmar versão final antes da publicação.',
]) ])
@php
$bandHref = $bandCtaHref ?? route('briefing');
@endphp
<section <section
aria-labelledby="packages-heading" aria-labelledby="packages-heading"
class="home-chapter border-b border-amare-border bg-amare-bg" class="home-chapter border-b border-amare-border bg-amare-bg"
@@ -72,12 +69,20 @@
</div> </div>
@endif @endif
@php($guidanceLink = \App\Support\PackageContactLink::forGuidance($settings))
@php($bandHref = filled($bandCtaHref) ? $bandCtaHref : $guidanceLink['href'])
@php($bandIsWhatsapp = ! filled($bandCtaHref) && $guidanceLink['isWhatsapp'])
<div class="mt-6 flex flex-col justify-between gap-8 bg-amare-accent-deep p-8 text-amare-accent-text md:flex-row md:items-center md:p-12" data-reveal data-reveal-from="up"> <div class="mt-6 flex flex-col justify-between gap-8 bg-amare-accent-deep p-8 text-amare-accent-text md:flex-row md:items-center md:p-12" data-reveal data-reveal-from="up">
<div class="max-w-xl space-y-3"> <div class="max-w-xl space-y-3">
<h3 class="text-[clamp(1.5625rem,2.7vw,2.125rem)] font-medium leading-tight">Ainda não sabe qual modalidade é ideal?</h3> <h3 class="text-[clamp(1.5625rem,2.7vw,2.125rem)] font-medium leading-tight">Ainda não sabe qual modalidade é ideal?</h3>
<p class="text-amare-accent-text/80">{{ $bandBody }}</p> <p class="text-amare-accent-text/80">{{ $bandBody }}</p>
</div> </div>
<a href="{{ $bandHref }}" class="inline-flex min-h-[48px] items-center justify-center self-start border border-amare-accent-text px-6 text-xs font-bold uppercase tracking-[0.09em] text-amare-accent-text transition-colors hover:bg-amare-accent-text hover:text-amare-accent-deep md:self-auto"> <a
data-testid="package-guidance-cta"
href="{{ $bandHref }}"
@if ($bandIsWhatsapp) target="_blank" rel="noopener noreferrer" @endif
class="inline-flex min-h-[48px] items-center justify-center self-start border border-amare-accent-text px-6 text-xs font-bold uppercase tracking-[0.09em] text-amare-accent-text transition-colors hover:bg-amare-accent-text hover:text-amare-accent-deep md:self-auto"
>
Conversar com a Amare Conversar com a Amare
</a> </a>
</div> </div>

View File

@@ -47,7 +47,6 @@
:show-intro="false" :show-intro="false"
kicker="tag" kicker="tag"
:show-subtitle="true" :show-subtitle="true"
:band-cta-href="route('briefing')"
band-body="Conte um pouco sobre o casamento. A Amare entende o momento de vocês e orienta o melhor formato de acompanhamento sem depender de um quiz automático." band-body="Conte um pouco sobre o casamento. A Amare entende o momento de vocês e orienta o melhor formato de acompanhamento sem depender de um quiz automático."
:show-note="false" :show-note="false"
/> />

View File

@@ -8,6 +8,7 @@ use App\Models\PortfolioCase;
use App\Models\SiteSetting; use App\Models\SiteSetting;
use App\Models\Testimonial; use App\Models\Testimonial;
use App\Models\WeddingPackage; use App\Models\WeddingPackage;
use App\Support\PackageContactLink;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase; use Tests\TestCase;
@@ -213,7 +214,12 @@ class HomePageContentTest extends TestCase
false, false,
) )
->assertSee('target="_blank"', false) ->assertSee('target="_blank"', false)
->assertDontSee(route('briefing', ['servico_interesse' => 'Grand Jour']), false); ->assertDontSee(route('briefing', ['servico_interesse' => 'Grand Jour']), false)
->assertSee('data-testid="package-guidance-cta"', false)
->assertSee(
'https://wa.me/5511988887777?text='.rawurlencode(PackageContactLink::GUIDANCE_MESSAGE),
false,
);
} }
public function test_corporate_steps_and_placeholder_render_from_settings(): void public function test_corporate_steps_and_placeholder_render_from_settings(): void

View File

@@ -6,6 +6,7 @@ namespace Tests\Feature\PublicSite;
use App\Models\SiteSetting; use App\Models\SiteSetting;
use App\Models\WeddingPackage; use App\Models\WeddingPackage;
use App\Support\PackageContactLink;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase; use Tests\TestCase;
@@ -31,7 +32,12 @@ class ServicesPageCtaTest extends TestCase
false, false,
) )
->assertSee('target="_blank"', false) ->assertSee('target="_blank"', false)
->assertDontSee(route('briefing', ['servico_interesse' => 'Grand Jour']), false); ->assertDontSee(route('briefing', ['servico_interesse' => 'Grand Jour']), false)
->assertSee('data-testid="package-guidance-cta"', false)
->assertSee(
'https://wa.me/5511988887777?text='.rawurlencode(PackageContactLink::GUIDANCE_MESSAGE),
false,
);
} }
public function test_package_cta_falls_back_to_briefing_without_whatsapp_number(): void public function test_package_cta_falls_back_to_briefing_without_whatsapp_number(): void