started on the admin dashboard
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Comment;
|
||||||
|
use App\Models\Upvote;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class AdminController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display the admin dashboard with statistics.
|
||||||
|
*/
|
||||||
|
public function dashboard()
|
||||||
|
{
|
||||||
|
// General Stats
|
||||||
|
$stats = [
|
||||||
|
'total_users' => 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'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -20,6 +20,12 @@
|
|||||||
Products
|
Products
|
||||||
</a>
|
</a>
|
||||||
@auth
|
@auth
|
||||||
|
@if(auth()->user()->hasRole('admin'))
|
||||||
|
<a href="{{ route('admin.dashboard') }}"
|
||||||
|
class="inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium {{ request()->routeIs('admin.*') ? 'border-primary-500 text-gray-900 dark:text-white' : 'border-transparent text-gray-500 dark:text-gray-400 hover:border-gray-300 dark:hover:border-gray-600 hover:text-gray-700 dark:hover:text-gray-300' }}">
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
@if(auth()->user()->hasAnyRole(['admin', 'moderator']))
|
@if(auth()->user()->hasAnyRole(['admin', 'moderator']))
|
||||||
<a href="{{ route('products.manage') }}"
|
<a href="{{ route('products.manage') }}"
|
||||||
class="inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium {{ request()->routeIs('products.manage') ? 'border-primary-500 text-gray-900 dark:text-white' : 'border-transparent text-gray-500 dark:text-gray-400 hover:border-gray-300 dark:hover:border-gray-600 hover:text-gray-700 dark:hover:text-gray-300' }}">
|
class="inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium {{ request()->routeIs('products.manage') ? 'border-primary-500 text-gray-900 dark:text-white' : 'border-transparent text-gray-500 dark:text-gray-400 hover:border-gray-300 dark:hover:border-gray-600 hover:text-gray-700 dark:hover:text-gray-300' }}">
|
||||||
@@ -162,6 +168,12 @@
|
|||||||
Discover
|
Discover
|
||||||
</a>
|
</a>
|
||||||
@auth
|
@auth
|
||||||
|
@if(auth()->user()->hasRole('admin'))
|
||||||
|
<a href="{{ route('admin.dashboard') }}"
|
||||||
|
class="block pl-3 pr-4 py-2 border-l-4 text-base font-medium {{ request()->routeIs('admin.*') ? 'border-primary-500 text-primary-700 bg-primary-50' : 'border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700' }}">
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
@if(auth()->user()->hasAnyRole(['admin', 'moderator']))
|
@if(auth()->user()->hasAnyRole(['admin', 'moderator']))
|
||||||
<a href="{{ route('products.manage') }}"
|
<a href="{{ route('products.manage') }}"
|
||||||
class="block pl-3 pr-4 py-2 border-l-4 text-base font-medium {{ request()->routeIs('products.manage') ? 'border-primary-500 text-primary-700 bg-primary-50' : 'border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700' }}">
|
class="block pl-3 pr-4 py-2 border-l-4 text-base font-medium {{ request()->routeIs('products.manage') ? 'border-primary-500 text-primary-700 bg-primary-50' : 'border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700' }}">
|
||||||
|
|||||||
+3
-4
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\AdminController;
|
||||||
use App\Http\Controllers\BookmarkController;
|
use App\Http\Controllers\BookmarkController;
|
||||||
use App\Http\Controllers\CommentController;
|
use App\Http\Controllers\CommentController;
|
||||||
use App\Http\Controllers\ProductController;
|
use App\Http\Controllers\ProductController;
|
||||||
@@ -53,11 +54,9 @@ Route::middleware(['auth', 'moderator'])->group(function () {
|
|||||||
Route::post('/products/{product}/reject', [ProductController::class, 'reject'])->name('products.reject');
|
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::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
|
||||||
Route::get('/dashboard', function () {
|
Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('dashboard');
|
||||||
return 'Admin Dashboard';
|
|
||||||
})->name('dashboard');
|
|
||||||
|
|
||||||
Route::get('/users', function () {
|
Route::get('/users', function () {
|
||||||
return 'User Management (Admin Only)';
|
return 'User Management (Admin Only)';
|
||||||
|
|||||||
Reference in New Issue
Block a user