diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php new file mode 100644 index 0000000..02aaa3c --- /dev/null +++ b/app/Http/Controllers/AdminController.php @@ -0,0 +1,81 @@ + User::count(), + 'total_products' => Product::count(), + 'approved_products' => Product::approved()->count(), + 'pending_products' => Product::pending()->count(), + 'rejected_products' => Product::rejected()->count(), + 'total_categories' => Category::count(), + 'total_comments' => Comment::count(), + 'total_upvotes' => Upvote::count(), + ]; + + // User Growth (last 7 days) + $userGrowth = User::where('created_at', '>=', now()->subDays(7)) + ->selectRaw('DATE(created_at) as date, COUNT(*) as count') + ->groupBy('date') + ->orderBy('date') + ->get(); + + // Product Growth (last 7 days) + $productGrowth = Product::where('created_at', '>=', now()->subDays(7)) + ->selectRaw('DATE(created_at) as date, COUNT(*) as count') + ->groupBy('date') + ->orderBy('date') + ->get(); + + // Top Categories (by product count) + $topCategories = Category::withCount('products') + ->orderBy('products_count', 'desc') + ->limit(5) + ->get(); + + // Recent Users + $recentUsers = User::with('roles') + ->latest() + ->limit(5) + ->get(); + + // Recent Products + $recentProducts = Product::with(['user', 'category']) + ->latest() + ->limit(5) + ->get(); + + // Most Upvoted Products + $topProducts = Product::approved() + ->withCount('upvotes') + ->orderBy('upvotes_count', 'desc') + ->limit(5) + ->get(); + + return view('admin.dashboard', compact( + 'stats', + 'userGrowth', + 'productGrowth', + 'topCategories', + 'recentUsers', + 'recentProducts', + 'topProducts' + )); + } +} diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php new file mode 100644 index 0000000..a9c42c5 --- /dev/null +++ b/resources/views/admin/dashboard.blade.php @@ -0,0 +1,254 @@ +@extends('layouts.app') + +@section('content') +
+
+ +
+

Admin Dashboard

+

Overview of your platform statistics and activity

+
+ + +
+ +
+
+
+
+ + + +
+
+
+
Total Users
+
{{ number_format($stats['total_users']) }}
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
Total Products
+
{{ number_format($stats['total_products']) }}
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
Pending Review
+
{{ number_format($stats['pending_products']) }}
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
Total Upvotes
+
{{ number_format($stats['total_upvotes']) }}
+
+
+
+
+
+
+ + +
+
+
Approved Products
+
{{ number_format($stats['approved_products']) }}
+
+
+
Rejected Products
+
{{ number_format($stats['rejected_products']) }}
+
+
+
Total Comments
+
{{ number_format($stats['total_comments']) }}
+
+
+
Categories
+
{{ number_format($stats['total_categories']) }}
+
+
+ + +
+ +
+
+

Top Categories

+
+
+
+ @forelse($topCategories as $category) +
+
+
+ {{ $loop->iteration }} +
+
+

{{ $category->name }}

+
+
+
+ {{ $category->products_count }} {{ Str::plural('product', $category->products_count) }} +
+
+ @empty +

No categories yet

+ @endforelse +
+
+
+ + +
+
+

Most Upvoted Products

+
+
+
+ @forelse($topProducts as $product) +
+
+
+ @if($product->thumbnail_url) + {{ $product->title }} + @else +
+ @endif +
+ +
+
+ {{ $product->upvotes_count }} 👍 +
+
+ @empty +

No products yet

+ @endforelse +
+
+
+
+ + +
+ +
+
+

Recent Users

+
+
+
+ @forelse($recentUsers as $user) +
+
+
+ {{ strtoupper(substr($user->name, 0, 1)) }} +
+
+ + {{ $user->name }} + +

{{ $user->created_at->diffForHumans() }}

+
+
+ @if($user->roles->isNotEmpty()) + + {{ $user->roles->first()->name }} + + @endif +
+ @empty +

No users yet

+ @endforelse +
+
+
+ + +
+
+

Recent Products

+
+
+
+ @forelse($recentProducts as $product) +
+
+
+ @if($product->thumbnail_url) + {{ $product->title }} + @else +
+ @endif +
+
+ + {{ $product->title }} + +

{{ $product->created_at->diffForHumans() }}

+
+
+ @if($product->isPending()) + + Pending + + @elseif($product->isApproved()) + + Approved + + @endif +
+ @empty +

No products yet

+ @endforelse +
+
+
+
+
+
+@endsection diff --git a/resources/views/components/layout/navbar.blade.php b/resources/views/components/layout/navbar.blade.php index 2e37f4d..31ed08e 100644 --- a/resources/views/components/layout/navbar.blade.php +++ b/resources/views/components/layout/navbar.blade.php @@ -20,6 +20,12 @@ Products @auth + @if(auth()->user()->hasRole('admin')) + + Dashboard + + @endif @if(auth()->user()->hasAnyRole(['admin', 'moderator'])) @@ -162,6 +168,12 @@ Discover @auth + @if(auth()->user()->hasRole('admin')) + + Dashboard + + @endif @if(auth()->user()->hasAnyRole(['admin', 'moderator'])) diff --git a/routes/web.php b/routes/web.php index 4d6a065..852a15e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,6 @@ group(function () { Route::post('/products/{product}/reject', [ProductController::class, 'reject'])->name('products.reject'); }); -// Admin Routes (example) +// Admin Routes Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () { - Route::get('/dashboard', function () { - return 'Admin Dashboard'; - })->name('dashboard'); + Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('dashboard'); Route::get('/users', function () { return 'User Management (Admin Only)';