nimuli/app/Livewire/Pages/Ai/Insights.php

93 lines
2.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Livewire\Pages\Ai;
use App\Domains\Ai\Services\AiService;
use App\Domains\Link\Models\Link;
use App\Domains\Workspace\Models\Workspace;
use Illuminate\View\View;
use Livewire\Component;
class Insights extends Component
{
public string $insights = '';
public string $error = '';
public int $workspaceId = 0;
public function mount(): void
{
$this->workspaceId = require_workspace()->id;
}
public function generate(): void
{
$this->error = '';
$this->insights = '';
if (! config('services.openai.api_key')) {
$this->error = 'OPENAI_API_KEY is not configured. Add it to .env and restart.';
return;
}
try {
$workspace = Workspace::findOrFail($this->workspaceId);
$topLinks = Link::where('workspace_id', $workspace->id)
->withCount('clicks')
->orderByDesc('clicks_count')
->limit(10)
->get(['slug', 'target_url', 'clicks_count']);
if ($topLinks->isEmpty()) {
$this->error = 'No links with clicks found. Create and share some links first.';
return;
}
$locale = auth()->user()?->locale ?? 'en';
$langMap = ['de' => 'German', 'en' => 'English', 'fr' => 'French', 'es' => 'Spanish', 'it' => 'Italian', 'pt' => 'Portuguese'];
$language = $langMap[$locale] ?? 'English';
$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);
if ($result === '') {
$this->error = 'AI returned an empty response. Check your API key and try again.';
return;
}
$this->insights = $result;
} catch (\Throwable $e) {
$this->error = 'Failed to generate insights: ' . $e->getMessage();
}
}
public function render(): View
{
return view('livewire.pages.ai.insights')
->layout('layouts.nimuli-app', ['title' => 'AI Insights']);
}
}