After picking who they are, users now pick what they want to achieve with TryPost. A multi-select goal step (12 options + an exclusive "just exploring" and "something else") sits between the persona step and connect, mirroring the persona screen's style. The goals persist to a json column on users and are mirrored to PostHog on identify (onboarding_goals array plus a boolean per goal), so campaigns can be cross-tabbed against the intent they actually attracted. connect now requires both a persona and at least one goal; persona store advances to the goal step. Options are grounded in TryPost's real capabilities (publishing, AI content, brand voice, automation via API/MCP, collaboration, analytics) and copy is localized in en/es/pt-BR.
40 lines
992 B
PHP
40 lines
992 B
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Requests\App\Onboarding;
|
|
|
|
use App\Enums\User\Goal;
|
|
use Illuminate\Contracts\Validation\Validator;
|
|
use Illuminate\Foundation\Http\FormRequest;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class StoreOnboardingGoalsRequest extends FormRequest
|
|
{
|
|
public function authorize(): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function rules(): array
|
|
{
|
|
return [
|
|
'goals' => ['required', 'array', 'min:1'],
|
|
'goals.*' => [Rule::enum(Goal::class)],
|
|
];
|
|
}
|
|
|
|
public function withValidator(Validator $validator): void
|
|
{
|
|
$validator->after(function (Validator $validator): void {
|
|
$goals = (array) $this->input('goals', []);
|
|
|
|
if (in_array(Goal::JustExploring->value, $goals, true) && count($goals) > 1) {
|
|
$validator->errors()->add('goals', __('onboarding.goals_exclusive'));
|
|
}
|
|
});
|
|
}
|
|
}
|