fix(ai): language-aware prompt, better insights, larger spinner

- Prompt respects user locale (de/en/fr/es/it/pt) — responds in user's language
- Rewrite prompt: domain pattern analysis, low-click diagnosis, no generic advice
- Include total clicks + link count for context
- max_tokens 512 → 800 for richer output
- Button spinner: h-5 w-5 (was h-4 w-4), bg-inherit to cover label text cleanly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
boban 2026-05-17 14:44:18 +02:00
parent d9f665f749
commit 8cd46398c0
3 changed files with 27 additions and 5 deletions

View File

@ -19,7 +19,7 @@ class AiService
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',
])->post('https://api.openai.com/v1/chat/completions', [ ])->post('https://api.openai.com/v1/chat/completions', [
'model' => $model, 'model' => $model,
'max_tokens' => 512, 'max_tokens' => 800,
'messages' => [['role' => 'user', 'content' => $prompt]], 'messages' => [['role' => 'user', 'content' => $prompt]],
]); ]);

View File

@ -45,9 +45,31 @@ class Insights extends Component
return; return;
} }
$summary = $topLinks->map(fn ($l) => "{$l->slug}: {$l->clicks_count} clicks → {$l->target_url}")->implode("\n"); $locale = auth()->user()?->locale ?? 'en';
$langMap = ['de' => 'German', 'en' => 'English', 'fr' => 'French', 'es' => 'Spanish', 'it' => 'Italian', 'pt' => 'Portuguese'];
$language = $langMap[$locale] ?? 'English';
$prompt = "You are a marketing analyst. Analyze these link performance stats and provide 3-5 actionable insights:\n\n{$summary}\n\nBe concise and specific."; $totalClicks = $topLinks->sum('clicks_count');
$linkCount = $topLinks->count();
$summary = $topLinks->map(fn ($l) => "- {$l->slug} ({$l->clicks_count} clicks) → {$l->target_url}")->implode("\n");
$prompt = <<<PROMPT
You are a link performance analyst for a URL shortener platform. Respond in {$language}.
Workspace: {$workspace->name}
Total links analysed: {$linkCount} | Total clicks: {$totalClicks}
Top links:
{$summary}
Provide 34 short, specific insights:
- Which link types or destinations perform best and why
- Patterns across target domains (e.g. social, docs, pricing pages)
- What the low-click links have in common and how to improve them
- One concrete next action for this workspace
No generic marketing advice. Base every insight on the data above. Be direct, no fluff.
PROMPT;
$result = app(AiService::class)->complete($prompt); $result = app(AiService::class)->complete($prompt);

View File

@ -25,8 +25,8 @@ $cls = $base . ' ' . ($variants[$variant] ?? $variants['primary']);
{{ $slot->isNotEmpty() ? $slot : $label }} {{ $slot->isNotEmpty() ? $slot : $label }}
</span> </span>
@if($action) @if($action)
<span wire:loading wire:target="{{ $action }}" class="absolute inset-0 flex items-center justify-center"> <span wire:loading wire:target="{{ $action }}" class="absolute inset-0 flex items-center justify-center rounded-lg bg-inherit">
<svg class="animate-spin h-4 w-4 flex-shrink-0" viewBox="0 0 24 24" fill="none"> <svg class="animate-spin h-5 w-5 flex-shrink-0" viewBox="0 0 24 24" fill="none">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/> <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/> <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/>
</svg> </svg>