started on the admin dashboard
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-gray-50 dark:bg-gray-900 min-h-screen">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<!-- Header -->
|
||||
<div class="mb-8">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Admin Dashboard</h1>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Overview of your platform statistics and activity</p>
|
||||
</div>
|
||||
|
||||
<!-- Stats Grid -->
|
||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4 mb-8">
|
||||
<!-- Total Users -->
|
||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<div class="p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 rounded-md p-3">
|
||||
<svg class="h-6 w-6 text-primary-600 dark:text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-5 w-0 flex-1">
|
||||
<dl>
|
||||
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Total Users</dt>
|
||||
<dd class="text-2xl font-semibold text-gray-900 dark:text-white">{{ number_format($stats['total_users']) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Total Products -->
|
||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<div class="p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 bg-green-100 dark:bg-green-900 rounded-md p-3">
|
||||
<svg class="h-6 w-6 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-5 w-0 flex-1">
|
||||
<dl>
|
||||
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Total Products</dt>
|
||||
<dd class="text-2xl font-semibold text-gray-900 dark:text-white">{{ number_format($stats['total_products']) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pending Products -->
|
||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<div class="p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 bg-yellow-100 dark:bg-yellow-900 rounded-md p-3">
|
||||
<svg class="h-6 w-6 text-yellow-600 dark:text-yellow-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-5 w-0 flex-1">
|
||||
<dl>
|
||||
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Pending Review</dt>
|
||||
<dd class="text-2xl font-semibold text-gray-900 dark:text-white">{{ number_format($stats['pending_products']) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Total Upvotes -->
|
||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<div class="p-6">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 bg-purple-100 dark:bg-purple-900 rounded-md p-3">
|
||||
<svg class="h-6 w-6 text-purple-600 dark:text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-5 w-0 flex-1">
|
||||
<dl>
|
||||
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">Total Upvotes</dt>
|
||||
<dd class="text-2xl font-semibold text-gray-900 dark:text-white">{{ number_format($stats['total_upvotes']) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Secondary Stats -->
|
||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4 mb-8">
|
||||
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="text-sm font-medium text-gray-500 dark:text-gray-400">Approved Products</div>
|
||||
<div class="mt-1 text-xl font-semibold text-green-600 dark:text-green-400">{{ number_format($stats['approved_products']) }}</div>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="text-sm font-medium text-gray-500 dark:text-gray-400">Rejected Products</div>
|
||||
<div class="mt-1 text-xl font-semibold text-red-600 dark:text-red-400">{{ number_format($stats['rejected_products']) }}</div>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="text-sm font-medium text-gray-500 dark:text-gray-400">Total Comments</div>
|
||||
<div class="mt-1 text-xl font-semibold text-gray-900 dark:text-white">{{ number_format($stats['total_comments']) }}</div>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="text-sm font-medium text-gray-500 dark:text-gray-400">Categories</div>
|
||||
<div class="mt-1 text-xl font-semibold text-gray-900 dark:text-white">{{ number_format($stats['total_categories']) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Two Column Layout -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8">
|
||||
<!-- Top Categories -->
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Top Categories</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="space-y-4">
|
||||
@forelse($topCategories as $category)
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 h-10 w-10 rounded-lg bg-primary-100 dark:bg-primary-900 flex items-center justify-center">
|
||||
<span class="text-primary-600 dark:text-primary-400 font-semibold">{{ $loop->iteration }}</span>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<p class="text-sm font-medium text-gray-900 dark:text-white">{{ $category->name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
{{ $category->products_count }} {{ Str::plural('product', $category->products_count) }}
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">No categories yet</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Most Upvoted Products -->
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Most Upvoted Products</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="space-y-4">
|
||||
@forelse($topProducts as $product)
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center min-w-0 flex-1">
|
||||
<div class="flex-shrink-0">
|
||||
@if($product->thumbnail_url)
|
||||
<img src="{{ $product->thumbnail_url }}" alt="{{ $product->title }}" class="h-10 w-10 rounded object-cover">
|
||||
@else
|
||||
<div class="h-10 w-10 rounded bg-gray-200 dark:bg-gray-700"></div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="ml-4 min-w-0 flex-1">
|
||||
<a href="{{ route('products.show', $product) }}" class="text-sm font-medium text-gray-900 dark:text-white hover:text-primary-600 dark:hover:text-primary-400 truncate block">
|
||||
{{ $product->title }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
{{ $product->upvotes_count }} 👍
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">No products yet</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent Activity -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<!-- Recent Users -->
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Recent Users</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="space-y-4">
|
||||
@forelse($recentUsers as $user)
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-gradient-to-br from-primary-500 to-accent-500 flex items-center justify-center text-white font-semibold">
|
||||
{{ strtoupper(substr($user->name, 0, 1)) }}
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<a href="{{ route('profile.show', $user) }}" class="text-sm font-medium text-gray-900 dark:text-white hover:text-primary-600 dark:hover:text-primary-400">
|
||||
{{ $user->name }}
|
||||
</a>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $user->created_at->diffForHumans() }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@if($user->roles->isNotEmpty())
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200">
|
||||
{{ $user->roles->first()->name }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">No users yet</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent Products -->
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Recent Products</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="space-y-4">
|
||||
@forelse($recentProducts as $product)
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center min-w-0 flex-1">
|
||||
<div class="flex-shrink-0">
|
||||
@if($product->thumbnail_url)
|
||||
<img src="{{ $product->thumbnail_url }}" alt="{{ $product->title }}" class="h-10 w-10 rounded object-cover">
|
||||
@else
|
||||
<div class="h-10 w-10 rounded bg-gray-200 dark:bg-gray-700"></div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="ml-4 min-w-0 flex-1">
|
||||
<a href="{{ route('products.show', $product) }}" class="text-sm font-medium text-gray-900 dark:text-white hover:text-primary-600 dark:hover:text-primary-400 truncate block">
|
||||
{{ $product->title }}
|
||||
</a>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $product->created_at->diffForHumans() }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@if($product->isPending())
|
||||
<span class="ml-4 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200">
|
||||
Pending
|
||||
</span>
|
||||
@elseif($product->isApproved())
|
||||
<span class="ml-4 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200">
|
||||
Approved
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">No products yet</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user