Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/Http/Controllers/Auth/RegisteredUserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:' . User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);

$role = \App\Models\Role::where('name', 'customer')->first();

$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'role_id' => $role ? $role->id : null,
]);

event(new Registered($user));
Expand Down
144 changes: 100 additions & 44 deletions resources/views/admin/dashboard.blade.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
<x-admin-layout>
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">Admin Dashboard</h1>
<p class="text-gray-500">Manage your service platform efficiently</p>
<div class="mb-8 animate-on-scroll">
<div class="bg-gradient-to-r from-red-600 to-orange-600 rounded-3xl p-8 text-white relative overflow-hidden shadow-2xl">
<div class="absolute top-0 right-0 -mt-20 -mr-20 w-80 h-80 bg-white/10 rounded-full blur-3xl"></div>
<div class="absolute bottom-0 left-0 -mb-20 -ml-20 w-60 h-60 bg-white/10 rounded-full blur-3xl"></div>

<div class="relative z-10">
<h1 class="text-3xl md:text-4xl font-black mb-2">
Admin Dashboard
</h1>
<p class="text-orange-100 text-lg">
Overview of your service booking platform performance
</p>
</div>
</div>
</div>

<!-- Stats Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300">
<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 card-hover">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-blue-100 text-blue-600 rounded-xl">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
Expand All @@ -15,24 +26,24 @@
</div>
<span class="text-green-500 text-sm font-semibold">+12%</span>
</div>
<h3 class="text-2xl font-bold text-gray-900">{{ $stats['total_bookings'] ?? 0 }}</h3>
<p class="text-gray-500 text-sm">Total Bookings</p>
<h3 class="text-3xl font-black text-gray-900">{{ $stats['total_bookings'] ?? 0 }}</h3>
<p class="text-gray-500 text-sm font-medium">Total Bookings</p>
</div>

<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300">
<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 card-hover">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-yellow-100 text-yellow-600 rounded-xl">
<svg class="w-6 h-6" 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>
<span class="text-xs font-semibold bg-yellow-100 text-yellow-700 px-2 py-1 rounded-full">Action Needed</span>
<span class="text-xs font-bold bg-yellow-100 text-yellow-700 px-2 py-1 rounded-full uppercase tracking-wide">Pending</span>
</div>
<h3 class="text-2xl font-bold text-gray-900">{{ $stats['pending_bookings'] ?? 0 }}</h3>
<p class="text-gray-500 text-sm">Pending Approval</p>
<h3 class="text-3xl font-black text-gray-900">{{ $stats['pending_bookings'] ?? 0 }}</h3>
<p class="text-gray-500 text-sm font-medium">Requiring Approval</p>
</div>

<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300">
<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 card-hover">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-green-100 text-green-600 rounded-xl">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
Expand All @@ -41,49 +52,66 @@
</div>
<span class="text-green-500 text-sm font-semibold">+8.2%</span>
</div>
<h3 class="text-2xl font-bold text-gray-900">${{ number_format($stats['total_revenue'] ?? 0, 2) }}</h3>
<p class="text-gray-500 text-sm">Total Revenue</p>
<h3 class="text-3xl font-black text-gray-900">${{ number_format($stats['total_revenue'] ?? 0, 2) }}</h3>
<p class="text-gray-500 text-sm font-medium">Total Revenue</p>
</div>

<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300">
<div class="bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 card-hover">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-purple-100 text-purple-600 rounded-xl">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
</svg>
</div>
</div>
<h3 class="text-2xl font-bold text-gray-900">{{ $stats['total_customers'] ?? 0 }}</h3>
<p class="text-gray-500 text-sm">Active Customers</p>
<h3 class="text-3xl font-black text-gray-900">{{ $stats['total_customers'] ?? 0 }}</h3>
<p class="text-gray-500 text-sm font-medium">Active Customers</p>
</div>
</div>

<!-- Quick Actions -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-gradient-to-r from-blue-500 to-blue-600 p-6 rounded-2xl shadow-lg text-white hover:shadow-xl transition-all duration-300">
<h3 class="text-lg font-bold mb-2">Manage Services</h3>
<p class="text-blue-100 mb-4">Add, edit, or remove services</p>
<a href="{{ route('admin.services.index') }}" class="inline-block bg-white text-blue-600 px-4 py-2 rounded-lg font-semibold hover:bg-blue-50 transition">Manage Services</a>
</div>
<a href="{{ route('admin.services.index') }}" class="group bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl hover:border-blue-500 transition-all duration-300">
<div class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center mb-4 group-hover:bg-blue-600 transition-colors">
<svg class="w-6 h-6 text-blue-600 group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<h3 class="text-lg font-bold text-gray-900 mb-2">Manage Services</h3>
<p class="text-gray-500 text-sm">Add, edit, or remove services</p>
</a>

<div class="bg-gradient-to-r from-green-500 to-green-600 p-6 rounded-2xl shadow-lg text-white hover:shadow-xl transition-all duration-300">
<h3 class="text-lg font-bold mb-2">Manage Workers</h3>
<p class="text-green-100 mb-4">Verify and manage service providers</p>
<a href="{{ route('admin.workers.index') }}" class="inline-block bg-white text-green-600 px-4 py-2 rounded-lg font-semibold hover:bg-green-50 transition">Manage Workers</a>
</div>
<a href="{{ route('admin.workers.index') }}" class="group bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl hover:border-green-500 transition-all duration-300">
<div class="w-12 h-12 bg-green-100 rounded-xl flex items-center justify-center mb-4 group-hover:bg-green-600 transition-colors">
<svg class="w-6 h-6 text-green-600 group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
</div>
<h3 class="text-lg font-bold text-gray-900 mb-2">Manage Workers</h3>
<p class="text-gray-500 text-sm">Verify and manage service providers</p>
</a>

<div class="bg-gradient-to-r from-purple-500 to-purple-600 p-6 rounded-2xl shadow-lg text-white hover:shadow-xl transition-all duration-300">
<h3 class="text-lg font-bold mb-2">View Bookings</h3>
<p class="text-purple-100 mb-4">Monitor and manage all bookings</p>
<a href="{{ route('admin.bookings.index') }}" class="inline-block bg-white text-purple-600 px-4 py-2 rounded-lg font-semibold hover:bg-purple-50 transition">View Bookings</a>
</div>
<a href="{{ route('admin.bookings.index') }}" class="group bg-white p-6 rounded-2xl shadow-lg border border-gray-100 hover:shadow-xl hover:border-purple-500 transition-all duration-300">
<div class="w-12 h-12 bg-purple-100 rounded-xl flex items-center justify-center mb-4 group-hover:bg-purple-600 transition-colors">
<svg class="w-6 h-6 text-purple-600 group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2H9a2 2 0 00-2-2V5a2 2 0 00-2-2h2a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2H9z" />
</svg>
</div>
<h3 class="text-lg font-bold text-gray-900 mb-2">View Bookings</h3>
<p class="text-gray-500 text-sm">Monitor and manage all bookings</p>
</a>
</div>

<!-- Recent Activity -->
<div class="bg-white rounded-2xl shadow-lg border border-gray-100 overflow-hidden">
<div class="px-6 py-4 border-b border-gray-100 flex justify-between items-center">
<div class="bg-white rounded-2xl shadow-lg border border-gray-100 overflow-hidden mb-12">
<div class="px-6 py-5 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
<h2 class="text-lg font-bold text-gray-900">Recent Bookings</h2>
<a href="{{ route('admin.bookings.index') }}" class="text-primary text-sm font-semibold hover:underline">View All</a>
<a href="{{ route('admin.bookings.index') }}" class="text-primary text-sm font-semibold hover:text-primary-dark transition-colors flex items-center gap-1">
View All
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</a>
</div>
<div class="overflow-x-auto">
<table class="w-full text-left text-sm text-gray-600">
Expand All @@ -99,29 +127,57 @@
</thead>
<tbody class="divide-y divide-gray-100">
@forelse($recent_bookings as $booking)
<tr class="hover:bg-gray-50 transition">
<td class="px-6 py-4 font-medium text-gray-900">{{ $booking->user->name ?? 'N/A' }}</td>
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-4">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-full bg-gradient-to-br from-gray-200 to-gray-300 flex items-center justify-center text-xs font-bold text-gray-600">
{{ substr($booking->user->name ?? 'U', 0, 1) }}
</div>
<span class="font-medium text-gray-900">{{ $booking->user->name ?? 'N/A' }}</span>
</div>
</td>
<td class="px-6 py-4">{{ $booking->service->name ?? 'N/A' }}</td>
<td class="px-6 py-4">
@if($booking->status == 'pending')
<span class="bg-yellow-100 text-yellow-700 px-2 py-1 rounded-full text-xs font-bold">Pending</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
<span class="w-1.5 h-1.5 bg-yellow-400 rounded-full mr-1.5"></span>
Pending
</span>
@elseif($booking->status == 'confirmed')
<span class="bg-blue-100 text-blue-700 px-2 py-1 rounded-full text-xs font-bold">Confirmed</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
<span class="w-1.5 h-1.5 bg-blue-400 rounded-full mr-1.5"></span>
Confirmed
</span>
@elseif($booking->status == 'completed')
<span class="bg-green-100 text-green-700 px-2 py-1 rounded-full text-xs font-bold">Completed</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
<span class="w-1.5 h-1.5 bg-green-400 rounded-full mr-1.5"></span>
Completed
</span>
@else
<span class="bg-red-100 text-red-700 px-2 py-1 rounded-full text-xs font-bold">{{ ucfirst($booking->status) }}</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
<span class="w-1.5 h-1.5 bg-red-400 rounded-full mr-1.5"></span>
{{ ucfirst($booking->status) }}
</span>
@endif
</td>
<td class="px-6 py-4">{{ $booking->created_at->format('M d, Y') }}</td>
<td class="px-6 py-4 font-semibold">${{ number_format($booking->total_amount ?? 0, 2) }}</td>
<td class="px-6 py-4 text-gray-500">{{ $booking->created_at->format('M d, Y') }}</td>
<td class="px-6 py-4 font-bold text-gray-900">${{ number_format($booking->total_amount ?? 0, 2) }}</td>
<td class="px-6 py-4">
<a href="{{ route('admin.bookings.show', $booking) }}" class="text-primary hover:text-primary-dark font-medium">Manage</a>
<a href="{{ route('admin.bookings.show', $booking) }}" class="text-primary hover:text-primary-dark font-medium text-sm transition-colors">Manage</a>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-8 text-center text-gray-500">No recent bookings found.</td>
<td colspan="6" class="px-6 py-12 text-center">
<div class="flex flex-col items-center justify-center">
<div class="w-12 h-12 bg-gray-100 rounded-full flex items-center justify-center mb-3">
<svg class="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2H9a2 2 0 00-2-2V5a2 2 0 00-2-2h2a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2H9z" />
</svg>
</div>
<span class="text-gray-500 font-medium">No recent bookings found</span>
</div>
</td>
</tr>
@endforelse
</tbody>
Expand Down
3 changes: 3 additions & 0 deletions resources/views/components/admin-layout.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@component('layouts.admin')
{{ $slot }}
@endcomponent
3 changes: 3 additions & 0 deletions resources/views/components/worker-layout.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@component('layouts.provider')
{{ $slot }}
@endcomponent
Loading