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
parent
d9f665f749
commit
8cd46398c0
|
|
@ -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]],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 3–4 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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue