229 lines
12 KiB
PHP
229 lines
12 KiB
PHP
@extends('layouts.admin')
|
|
|
|
@section('title', 'Admin Dashboard - JobifyGarden')
|
|
|
|
@section('content')
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<!-- Header -->
|
|
<div class="flex justify-between items-center mb-8">
|
|
<h1 class="text-3xl font-bold text-gray-900">Admin Dashboard</h1>
|
|
<div class="flex gap-2 items-center">
|
|
<a href="{{ route('admin.logs.api') }}" class="px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-md">API Logs</a>
|
|
<a href="{{ route('admin.logs.fetch') }}" class="px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-md">Fetch Logs</a>
|
|
<form method="POST" action="{{ route('logout') }}">
|
|
@csrf
|
|
<button type="submit" class="px-4 py-2 bg-red-100 hover:bg-red-200 text-red-700 rounded-md">Logout</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Time Period Selector -->
|
|
<div class="mb-6">
|
|
<label class="text-sm font-medium text-gray-700 mr-2">Time Period:</label>
|
|
<select onchange="window.location.href='?days=' + this.value" class="px-3 py-2 border border-gray-300 rounded-md">
|
|
<option value="1" {{ $days == 1 ? 'selected' : '' }}>Last 24 hours</option>
|
|
<option value="7" {{ $days == 7 ? 'selected' : '' }}>Last 7 days</option>
|
|
<option value="30" {{ $days == 30 ? 'selected' : '' }}>Last 30 days</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- System Health -->
|
|
<div class="mb-8">
|
|
<h2 class="text-xl font-semibold text-gray-900 mb-4">System Health</h2>
|
|
<div class="bg-white rounded-lg shadow-sm border p-6">
|
|
<div class="flex items-center">
|
|
<div class="text-4xl mr-4">
|
|
@if($metrics['health']['status'] === 'healthy')
|
|
<span class="text-green-500">✓</span>
|
|
@elseif($metrics['health']['status'] === 'warning')
|
|
<span class="text-yellow-500">⚠</span>
|
|
@else
|
|
<span class="text-red-500">✗</span>
|
|
@endif
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-bold capitalize {{ $metrics['health']['status'] === 'healthy' ? 'text-green-600' : ($metrics['health']['status'] === 'warning' ? 'text-yellow-600' : 'text-red-600') }}">
|
|
{{ $metrics['health']['status'] }}
|
|
</div>
|
|
<div class="text-sm text-gray-600">
|
|
API Failures (1h): {{ $metrics['health']['api_failures_last_hour'] }} |
|
|
Fetch Failures (24h): {{ $metrics['health']['fetch_failures_last_24h'] }}
|
|
</div>
|
|
@if($metrics['health']['last_successful_fetch'])
|
|
<div class="text-xs text-gray-500 mt-1">
|
|
Last successful fetch: {{ $metrics['health']['last_successful_fetch']->diffForHumans() }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- API Metrics -->
|
|
<div class="mb-8">
|
|
<h2 class="text-xl font-semibold text-gray-900 mb-4">API Performance</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Total Requests</div>
|
|
<div class="text-2xl font-bold text-gray-900">{{ number_format($metrics['api']['total_requests']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Success Rate</div>
|
|
<div class="text-2xl font-bold text-green-600">{{ $metrics['api']['success_rate'] }}%</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Failed Requests</div>
|
|
<div class="text-2xl font-bold text-red-600">{{ number_format($metrics['api']['failed_requests']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Avg Response Time</div>
|
|
<div class="text-2xl font-bold text-gray-900">{{ round($metrics['api']['average_response_time']) }}ms</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Job Fetch Metrics -->
|
|
<div class="mb-8">
|
|
<h2 class="text-xl font-semibold text-gray-900 mb-4">Job Fetching</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Total Fetches</div>
|
|
<div class="text-2xl font-bold text-gray-900">{{ number_format($metrics['fetch']['total_fetches']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Jobs Created</div>
|
|
<div class="text-2xl font-bold text-emerald-600">{{ number_format($metrics['fetch']['total_jobs_created']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Jobs Updated</div>
|
|
<div class="text-2xl font-bold text-blue-600">{{ number_format($metrics['fetch']['total_jobs_updated']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Avg Duration</div>
|
|
<div class="text-2xl font-bold text-gray-900">{{ round($metrics['fetch']['average_duration']) }}s</div>
|
|
</div>
|
|
</div>
|
|
|
|
@if(!empty($metrics['fetch']['by_source']))
|
|
<div class="bg-white rounded-lg shadow-sm border p-6">
|
|
<h3 class="font-semibold text-gray-900 mb-4">By Source</h3>
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead>
|
|
<tr>
|
|
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Source</th>
|
|
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Fetches</th>
|
|
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Created</th>
|
|
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Updated</th>
|
|
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Avg Duration</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200">
|
|
@foreach($metrics['fetch']['by_source'] as $source)
|
|
<tr>
|
|
<td class="px-4 py-2 text-sm text-gray-900">{{ $source['source'] }}</td>
|
|
<td class="px-4 py-2 text-sm text-gray-900">{{ number_format($source['total_fetches']) }}</td>
|
|
<td class="px-4 py-2 text-sm text-emerald-600">{{ number_format($source['jobs_created']) }}</td>
|
|
<td class="px-4 py-2 text-sm text-blue-600">{{ number_format($source['jobs_updated']) }}</td>
|
|
<td class="px-4 py-2 text-sm text-gray-900">{{ $source['avg_duration'] }}s</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Analytics Metrics -->
|
|
<div class="mb-8">
|
|
<h2 class="text-xl font-semibold text-gray-900 mb-4">User Analytics</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Job Views</div>
|
|
<div class="text-2xl font-bold text-gray-900">{{ number_format($metrics['analytics']['job_views']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Apply Clicks</div>
|
|
<div class="text-2xl font-bold text-emerald-600">{{ number_format($metrics['analytics']['job_apply_clicks']) }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">CTR</div>
|
|
<div class="text-2xl font-bold text-blue-600">{{ $metrics['analytics']['click_through_rate'] }}%</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm border p-4">
|
|
<div class="text-sm text-gray-600">Unique Sessions</div>
|
|
<div class="text-2xl font-bold text-gray-900">{{ number_format($metrics['analytics']['unique_sessions']) }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<!-- Popular Jobs -->
|
|
@if(!empty($metrics['analytics']['popular_jobs']))
|
|
<div class="bg-white rounded-lg shadow-sm border p-6">
|
|
<h3 class="font-semibold text-gray-900 mb-4">Most Viewed Jobs</h3>
|
|
<div class="space-y-2">
|
|
@foreach($metrics['analytics']['popular_jobs'] as $job)
|
|
<div class="flex justify-between items-center py-2 border-b border-gray-100">
|
|
<div class="flex-1">
|
|
<div class="text-sm font-medium text-gray-900">{{ $job['title'] }}</div>
|
|
<div class="text-xs text-gray-500">{{ $job['company'] }}</div>
|
|
</div>
|
|
<div class="text-right ml-4">
|
|
<div class="text-sm font-medium text-gray-900">{{ $job['views'] }} views</div>
|
|
<div class="text-xs text-emerald-600">{{ $job['apply_clicks'] }} applies</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- Popular Searches -->
|
|
@if(!empty($metrics['analytics']['popular_searches']))
|
|
<div class="bg-white rounded-lg shadow-sm border p-6">
|
|
<h3 class="font-semibold text-gray-900 mb-4">Popular Searches</h3>
|
|
<div class="space-y-2">
|
|
@foreach($metrics['analytics']['popular_searches'] as $search)
|
|
<div class="flex justify-between items-center py-2 border-b border-gray-100">
|
|
<div class="text-sm font-medium text-gray-900">{{ $search['term'] }}</div>
|
|
<div class="text-sm text-gray-600">{{ $search['count'] }} searches</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Source Status -->
|
|
<div class="mb-8">
|
|
<h2 class="text-xl font-semibold text-gray-900 mb-4">Job Sources Status</h2>
|
|
<div class="bg-white rounded-lg shadow-sm border p-6">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
@foreach($metrics['health']['sources_status'] as $source)
|
|
<div class="border rounded-lg p-4">
|
|
<div class="flex justify-between items-start mb-2">
|
|
<h4 class="font-semibold text-gray-900">{{ $source['name'] }}</h4>
|
|
<span class="px-2 py-1 rounded text-xs {{ $source['is_active'] ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800' }}">
|
|
{{ $source['is_active'] ? 'Active' : 'Inactive' }}
|
|
</span>
|
|
</div>
|
|
@if($source['last_fetch_at'])
|
|
<div class="text-xs text-gray-600 mb-1">
|
|
Last fetch: {{ \Carbon\Carbon::parse($source['last_fetch_at'])->diffForHumans() }}
|
|
</div>
|
|
<div class="text-xs {{ $source['last_fetch_success'] ? 'text-green-600' : 'text-red-600' }}">
|
|
{{ $source['last_fetch_success'] ? 'Success' : 'Failed' }} | {{ $source['jobs_in_last_fetch'] }} jobs
|
|
</div>
|
|
@else
|
|
<div class="text-xs text-gray-500">No fetches yet</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|