PATH:
home
/
cardxfeb
/
public_html
/
app
/
Http
/
Controllers
/
Editing: OnboardingController.php
<?php namespace App\Http\Controllers; use App\Jobs\GenerateAiCardJob; use App\Models\Vcard; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; use Illuminate\Validation\Rule; class OnboardingController extends Controller { /** Show the onboarding form */ public function create() { return view('vcard.onboarding'); } /** * Store: accept 15 source URLs, create VCard skeleton, dispatch AI job. * Input: sources[] array (or legacy social_url string) */ public function store(Request $request): \Illuminate\Http\RedirectResponse { // Support both legacy single URL and new multi-source array if ($request->has('social_url') && !$request->has('sources')) { $request->merge(['sources' => [$request->input('social_url')]]); } $request->validate([ 'sources' => ['required', 'array', 'min:1', 'max:5'], 'sources.*' => ['required', 'url', 'max:500', 'distinct'], ], [ 'sources.required' => 'Fornea pelo menos uma URL de rede social ou site.', 'sources.max' => 'Pode fornecer no mximo 5 fontes.', 'sources.*.url' => 'Uma das URLs fornecidas no vlida.', 'sources.*.distinct' => 'No repita URLs.', ]); $user = Auth::user(); $sources = array_filter($request->sources, fn($s) => !empty(trim($s))); // Determine primary URL for backward compatibility $primaryUrl = $sources[0] ?? ''; // Create VCard skeleton $vcard = Vcard::create([ 'user_id' => $user->id, 'tenant_id' => $user->tenant_id ?? null, 'name' => $user->name, 'url_alias' => 'card-' . uniqid(), 'status' => 'pending_payment', 'ai_status' => 'pending', 'ai_social_url' => json_encode(array_values($sources), JSON_UNESCAPED_SLASHES), 'payment_deadline' => now()->addHours(24), 'template_id' => 1, ]); Log::info("[Onboarding] VCard#{$vcard->id} created. Sources: " . implode(', ', $sources)); // Dispatch AI job with full sources array GenerateAiCardJob::dispatch($user, $sources, $vcard->id) ->onQueue('ai-generation'); return redirect()->route('vcard.processing', ['vcard' => $vcard->id]) ->with('message', count($sources) > 1 ? 'A IA est a analisar ' . count($sources) . ' fontes para criar o seu carto...' : 'A IA est a preparar o seu carto...' ); } /** Show processing screen */ public function processing(Vcard $vcard) { if ($vcard->user_id !== Auth::id()) { abort(403); } return view('vcard.processing', compact('vcard')); } /** API: Poll AI status */ public function aiStatus(Vcard $vcard): JsonResponse { if ($vcard->user_id !== Auth::id()) { return response()->json(['error' => 'Unauthorized'], 403); } $aiData = null; if ($vcard->ai_status === 'completed' && $vcard->ai_data) { $decoded = json_decode($vcard->ai_data, true); $aiData = [ 'template_id' => $decoded['template_id'] ?? null, 'color_primary' => $decoded['color_primary'] ?? null, 'confidence' => $decoded['confidence'] ?? null, 'brand_personality' => $decoded['brand_personality'] ?? null, ]; } return response()->json([ 'vcard_id' => $vcard->id, 'ai_status' => $vcard->ai_status, 'template_id' => $vcard->template_id, 'ai_data' => $aiData, 'redirect_url' => $vcard->ai_status === 'completed' ? route('user.vcard.edit', $vcard->id) : null, ]); } }
SAVE
CANCEL