222 lines
10 KiB
PHP
222 lines
10 KiB
PHP
@extends('layouts.admin')
|
|
|
|
@section('title', 'Dashboard')
|
|
|
|
@section('breadcrumb')
|
|
<li class="breadcrumb-item active">Dashboard</li>
|
|
@endsection
|
|
|
|
@section('content')
|
|
<div class="d-flex align-items-center justify-content-between mb-4">
|
|
<h4 class="mb-0 fw-bold">Dashboard</h4>
|
|
<span class="text-muted small">{{ now()->format('d M Y, H:i') }}</span>
|
|
</div>
|
|
|
|
{{-- Status Perkhidmatan --}}
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-6">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body py-2 px-3">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<span class="small fw-semibold text-muted">Ollama</span>
|
|
@if($health['ollama']['online'])
|
|
<span class="badge bg-success"><i class="bi bi-circle-fill me-1" style="font-size:.5rem"></i>Online</span>
|
|
@else
|
|
<span class="badge bg-danger"><i class="bi bi-circle-fill me-1" style="font-size:.5rem"></i>Offline</span>
|
|
@endif
|
|
</div>
|
|
@if($health['ollama']['online'])
|
|
<div class="d-flex gap-2 mt-1">
|
|
<span class="badge {{ $health['ollama']['chat_model'] ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning' }} small">
|
|
Chat: {{ config('ollama.chat_model') }}
|
|
</span>
|
|
<span class="badge {{ $health['ollama']['embed_model'] ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning' }} small">
|
|
Embed: {{ config('ollama.embedding_model') }}
|
|
</span>
|
|
</div>
|
|
@elseif($health['ollama']['error'])
|
|
<small class="text-danger">{{ $health['ollama']['error'] }}</small>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body py-2 px-3">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<span class="small fw-semibold text-muted">Qdrant</span>
|
|
@if($health['qdrant']['online'])
|
|
<span class="badge bg-success"><i class="bi bi-circle-fill me-1" style="font-size:.5rem"></i>Online</span>
|
|
@else
|
|
<span class="badge bg-danger"><i class="bi bi-circle-fill me-1" style="font-size:.5rem"></i>Offline</span>
|
|
@endif
|
|
</div>
|
|
@if($health['qdrant']['online'])
|
|
<div class="mt-1">
|
|
<span class="badge bg-info-subtle text-info small">
|
|
{{ number_format($health['qdrant']['points_count'] ?? 0) }} vectors
|
|
</span>
|
|
</div>
|
|
@elseif($health['qdrant']['error'])
|
|
<small class="text-danger">{{ $health['qdrant']['error'] }}</small>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Stats Cards --}}
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div>
|
|
<div class="text-muted small">Dokumen Aktif</div>
|
|
<div class="fs-3 fw-bold text-primary">{{ $stats['active_documents'] }}</div>
|
|
<div class="text-muted small">dari {{ $stats['total_documents'] }} dokumen</div>
|
|
</div>
|
|
<i class="bi bi-file-pdf fs-1 text-primary opacity-25"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div>
|
|
<div class="text-muted small">FAQ & Pengetahuan</div>
|
|
<div class="fs-3 fw-bold text-success">{{ $stats['total_knowledge_items'] }}</div>
|
|
<div class="text-muted small">item aktif</div>
|
|
</div>
|
|
<i class="bi bi-lightbulb fs-1 text-success opacity-25"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div>
|
|
<div class="text-muted small">Chat Hari Ini</div>
|
|
<div class="fs-3 fw-bold text-info">{{ $stats['total_chats_today'] }}</div>
|
|
<div class="text-muted small">pertanyaan</div>
|
|
</div>
|
|
<i class="bi bi-chat-dots fs-1 text-info opacity-25"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card border-0 shadow-sm {{ $stats['flagged_chats'] > 0 ? 'border-warning' : '' }}">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div>
|
|
<div class="text-muted small">Perlu Semakan</div>
|
|
<div class="fs-3 fw-bold {{ $stats['flagged_chats'] > 0 ? 'text-warning' : 'text-muted' }}">
|
|
{{ $stats['flagged_chats'] }}
|
|
</div>
|
|
<div class="text-muted small">log ditanda</div>
|
|
</div>
|
|
<i class="bi bi-flag fs-1 text-warning opacity-25"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Processing Status & Recent Activity --}}
|
|
<div class="row g-3">
|
|
<div class="col-lg-4">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-bottom">
|
|
<h6 class="mb-0 fw-semibold">Status Pemprosesan</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
@if($stats['processing_documents'] > 0)
|
|
<div class="d-flex align-items-center justify-content-between mb-2">
|
|
<span class="small">Sedang diproses</span>
|
|
<span class="badge bg-warning">{{ $stats['processing_documents'] }}</span>
|
|
</div>
|
|
@endif
|
|
@if($stats['failed_documents'] > 0)
|
|
<div class="d-flex align-items-center justify-content-between mb-2">
|
|
<span class="small text-danger">Gagal diproses</span>
|
|
<a href="{{ route('admin.documents.index', ['status' => 'failed']) }}"
|
|
class="badge bg-danger text-decoration-none">{{ $stats['failed_documents'] }}</a>
|
|
</div>
|
|
@endif
|
|
@if($stats['unanswered_chats'] > 0)
|
|
<div class="d-flex align-items-center justify-content-between mb-2">
|
|
<span class="small">Soalan tidak terjawab</span>
|
|
<a href="{{ route('admin.chat-feedback.index', ['has_answer' => 0]) }}"
|
|
class="badge bg-secondary text-decoration-none">{{ $stats['unanswered_chats'] }}</a>
|
|
</div>
|
|
@endif
|
|
@if($stats['processing_documents'] == 0 && $stats['failed_documents'] == 0)
|
|
<p class="text-muted small mb-0"><i class="bi bi-check-circle text-success me-1"></i>Semua dokumen diproses.</p>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card border-0 shadow-sm mt-3">
|
|
<div class="card-header bg-white border-bottom">
|
|
<h6 class="mb-0 fw-semibold">Chat Terkini</h6>
|
|
</div>
|
|
<ul class="list-group list-group-flush">
|
|
@forelse($recentChats as $chat)
|
|
<li class="list-group-item py-2 px-3">
|
|
<div class="text-truncate small fw-semibold">{{ $chat->question }}</div>
|
|
<div class="d-flex align-items-center gap-2 mt-1">
|
|
@if($chat->category)
|
|
<span class="badge bg-light text-dark border" style="font-size:.65rem">{{ $chat->category->name }}</span>
|
|
@endif
|
|
@if(!$chat->has_answer)
|
|
<span class="badge bg-warning-subtle text-warning border border-warning" style="font-size:.65rem">Tidak Terjawab</span>
|
|
@endif
|
|
<span class="text-muted ms-auto" style="font-size:.65rem">{{ $chat->created_at->diffForHumans() }}</span>
|
|
</div>
|
|
</li>
|
|
@empty
|
|
<li class="list-group-item py-3 text-center text-muted small">Tiada chat lagi.</li>
|
|
@endforelse
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-8">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-bottom d-flex align-items-center justify-content-between">
|
|
<h6 class="mb-0 fw-semibold">Aktiviti Terkini</h6>
|
|
<a href="{{ route('admin.audit-logs.index') }}" class="btn btn-sm btn-link p-0 text-muted">
|
|
Lihat semua
|
|
</a>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-hover mb-0">
|
|
<tbody>
|
|
@forelse($recentActivity as $log)
|
|
<tr>
|
|
<td class="ps-3 py-2">
|
|
<div class="small fw-semibold">{{ $log->description ?? $log->event }}</div>
|
|
@if($log->user)
|
|
<small class="text-muted">{{ $log->user->name }}</small>
|
|
@endif
|
|
</td>
|
|
<td class="text-end pe-3 py-2 text-muted small" style="white-space:nowrap">
|
|
{{ $log->created_at->diffForHumans() }}
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr><td colspan="2" class="text-center text-muted py-4 small">Tiada aktiviti.</td></tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|