carrentalservice/resources/views/dashboard.blade.php
2026-02-19 22:05:20 +00:00

1171 lines
65 KiB
PHP

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ config('settings.company_name') }} - Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<script>
// Dark mode
if (localStorage.getItem('darkMode') === 'true' || (!localStorage.getItem('darkMode') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
}
function toggleDarkMode() {
document.documentElement.classList.toggle('dark');
localStorage.setItem('darkMode', document.documentElement.classList.contains('dark'));
updateDarkModeBtn();
}
function updateDarkModeBtn() {
const isDark = document.documentElement.classList.contains('dark');
const btn = document.getElementById('darkModeBtn');
if(btn) {
btn.innerHTML = isDark ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>';
}
}
</script>
</head>
<body class="bg-gray-100 dark:bg-slate-900 min-h-screen transition-colors">
<!-- Sidebar -->
<div class="fixed left-0 top-0 h-full w-64 bg-slate-800">
<div class="p-6 border-b border-slate-700">
<h1 class="text-xl font-bold text-white flex items-center gap-2">
@if(config('settings.logo'))
<img src="{{ asset(config('settings.logo')) }}" alt="Logo" class="w-8 h-8 object-contain">
@else
<i class="fas fa-road text-blue-400"></i>
@endif
{{ config('settings.company_name') }}
</h1>
<p class="text-slate-400 text-xs mt-1">{{ config('settings.company_tagline') }}</p>
</div>
<nav class="mt-4 px-4">
<a href="{{ route('dashboard') }}" class="flex items-center gap-3 px-4 py-3 rounded-lg {{ request()->routeIs('dashboard') ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-slate-700' }}">
<i class="fas fa-chart-line w-5"></i> Dashboard
</a>
<a href="{{ route('cars.index') }}" class="flex items-center gap-3 px-4 py-3 rounded-lg {{ request()->routeIs('cars.*') ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-slate-700' }} mt-1">
<i class="fas fa-car w-5"></i> Fleet
</a>
<a href="{{ route('customers.index') }}" class="flex items-center gap-3 px-4 py-3 rounded-lg {{ request()->routeIs('customers.*') ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-slate-700' }} mt-1">
<i class="fas fa-users w-5"></i> Customers
</a>
<a href="{{ route('rentals.index') }}" class="flex items-center gap-3 px-4 py-3 rounded-lg {{ request()->routeIs('rentals.*') ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-slate-700' }} mt-1">
<i class="fas fa-calendar-check w-5"></i> Rentals
</a>
<a href="{{ route('services.index') }}" class="flex items-center gap-3 px-4 py-3 rounded-lg {{ request()->routeIs('services.*') ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-slate-700' }} mt-1">
<i class="fas fa-tools w-5"></i> Services
</a>
<a href="{{ route('payments.index') }}" class="flex items-center gap-3 px-4 py-3 rounded-lg {{ request()->routeIs('payments.*') ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-slate-700' }} mt-1">
<i class="fas fa-credit-card w-5"></i> Payments
</a>
<a href="{{ route('settings.index') }}" class="flex items-center gap-3 px-4 py-3 rounded-lg {{ request()->routeIs('settings.*') ? 'bg-blue-600 text-white' : 'text-slate-300 hover:bg-slate-700' }} mt-1">
<i class="fas fa-cog w-5"></i> Settings
</a>
</nav>
</div>
<!-- Main Content -->
<div class="ml-64 p-8">
<!-- Header -->
<div class="flex justify-between items-center mb-8">
<div>
<h1 class="text-2xl font-bold text-gray-800">Dashboard</h1>
<p class="text-gray-500 text-sm">Fleet overview and statistics</p>
</div>
<div class="flex items-center gap-3">
<button onclick="toggleDarkMode()" id="darkModeBtn" class="bg-white dark:bg-slate-800 text-gray-600 dark:text-gray-300 px-4 py-2 rounded-lg border border-gray-200 dark:border-slate-700 hover:bg-gray-50 dark:hover:bg-slate-700">
<i class="fas fa-moon"></i>
</button>
<span class="bg-white dark:bg-slate-800 text-gray-600 dark:text-gray-300 px-4 py-2 rounded-lg border border-gray-200 dark:border-slate-700 text-sm">
<i class="fas fa-calendar-alt mr-2 text-gray-400"></i>
{{ now()->format('M d, Y') }}
</span>
</div>
</div>
<!-- Quick Actions -->
<div class="mb-6 bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-gray-200 dark:border-slate-700 p-4">
<div class="flex flex-wrap gap-2">
<button onclick="openQuickRentModal()" class="flex items-center gap-2 bg-gradient-to-r from-amber-500 to-orange-600 text-white px-4 py-2 rounded-lg hover:from-amber-600 hover:to-orange-700 text-sm font-medium">
<i class="fas fa-bolt"></i> Quick Rent
</button>
<a href="{{ route('cars.create') }}" class="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 text-sm font-medium">
<i class="fas fa-plus"></i> Add Car
</a>
<a href="{{ route('customers.create') }}" class="flex items-center gap-2 bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 text-sm font-medium">
<i class="fas fa-user-plus"></i> Add Customer
</a>
<a href="{{ route('rentals.create') }}" class="flex items-center gap-2 bg-slate-600 text-white px-4 py-2 rounded-lg hover:bg-slate-700 text-sm font-medium">
<i class="fas fa-calendar-plus"></i> New Rental
</a>
<a href="{{ route('services.create') }}" class="flex items-center gap-2 bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 text-sm font-medium">
<i class="fas fa-calendar-check"></i> Schedule Service
</a>
</div>
</div>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-5 mb-8">
<!-- Total Cars -->
<a href="{{ route('cars.index') }}" class="bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-gray-200 dark:border-slate-700 p-5 hover:border-blue-400 transition">
<div class="flex justify-between items-start">
<div>
<p class="text-gray-500 text-sm font-medium">Total Fleet</p>
<p class="text-3xl font-bold text-gray-800 mt-1">{{ $totalCars }}</p>
<p class="text-green-600 text-sm mt-2 font-medium">
{{ $availableCars }} available
</p>
</div>
<div class="w-12 h-12 rounded-lg bg-blue-50 flex items-center justify-center">
<i class="fas fa-car text-blue-600 text-xl"></i>
</div>
</div>
</a>
<!-- Active Rentals -->
<a href="{{ route('rentals.index') }}" class="bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-gray-200 dark:border-slate-700 p-5 hover:border-amber-400 transition">
<div class="flex justify-between items-start">
<div>
<p class="text-gray-500 text-sm font-medium">Active Rentals</p>
<p class="text-3xl font-bold text-gray-800 mt-1">{{ $activeRentals }}</p>
<p class="text-amber-600 text-sm mt-2 font-medium">
{{ $pendingRentals }} pending
</p>
</div>
<div class="w-12 h-12 rounded-lg bg-amber-50 flex items-center justify-center">
<i class="fas fa-calendar-check text-amber-600 text-xl"></i>
</div>
</div>
</a>
<!-- Customers -->
<a href="{{ route('customers.index') }}" class="bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-gray-200 dark:border-slate-700 p-5 hover:border-purple-400 transition">
<div class="flex justify-between items-start">
<div>
<p class="text-gray-500 text-sm font-medium">Customers</p>
<p class="text-3xl font-bold text-gray-800 mt-1">{{ $totalCustomers }}</p>
<p class="text-purple-600 text-sm mt-2 font-medium">
{{ $activeCustomers }} active
</p>
</div>
<div class="w-12 h-12 rounded-lg bg-purple-50 flex items-center justify-center">
<i class="fas fa-users text-purple-600 text-xl"></i>
</div>
</div>
</a>
<!-- Revenue -->
<a href="{{ route('payments.index') }}" class="bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-gray-200 dark:border-slate-700 p-5 hover:border-green-400 transition">
<div class="flex justify-between items-start">
<div>
<p class="text-gray-500 text-sm font-medium">Total Revenue</p>
<p class="text-3xl font-bold text-gray-800 mt-1"> BHD {{ number_format($totalRevenue, 0) }}</p>
<p class="text-green-600 text-sm mt-2 font-medium">
BHD {{ number_format($monthlyRevenue, 0) }} this month
</p>
</div>
<div class="w-12 h-12 rounded-lg bg-green-50 flex items-center justify-center">
<i class="fas fa-dollar-sign text-green-600 text-xl"></i>
</div>
</div>
</a>
</div>
<!-- Charts Row -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-5 mb-8">
<!-- Revenue Chart (2/3 width) -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 lg:col-span-2">
<h3 class="text-gray-800 dark:text-white font-semibold mb-2">Revenue Overview</h3>
<canvas id="revenueChart" height="140"></canvas>
</div>
<!-- Fleet Status (1/3 width) -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 flex flex-col">
<h3 class="text-gray-800 dark:text-white font-semibold mb-2">Fleet Status</h3>
<div class="flex-1 flex items-center justify-center">
<canvas id="fleetChart"></canvas>
</div>
</div>
</div>
<!-- Second Row -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-5 mb-8">
<!-- Rentals Trend -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 lg:col-span-2">
<h3 class="text-gray-800 dark:text-white font-semibold mb-2">Rentals Trend (Last 6 Months)</h3>
<canvas id="rentalsChart" height="100"></canvas>
</div>
<!-- Service Stats -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<h3 class="text-gray-800 dark:text-white font-semibold mb-3">Service Center</h3>
<div class="space-y-2">
<div class="flex justify-between items-center p-2 bg-gray-50 rounded-lg">
<span class="text-gray-600 text-sm">Total Services</span>
<span class="text-gray-800 font-semibold text-sm">{{ $totalServices }}</span>
</div>
<div class="flex justify-between items-center p-2 bg-gray-50 rounded-lg">
<span class="text-gray-600 text-sm">Pending</span>
<span class="text-amber-600 font-semibold text-sm">{{ $pendingServices }}</span>
</div>
<div class="flex justify-between items-center p-2 bg-gray-50 rounded-lg">
<span class="text-gray-600 text-sm">Total Cost</span>
<span class="text-red-600 font-semibold text-sm"> BHD {{ number_format($totalServiceCost, 0) }}</span>
</div>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5">
<!-- Recent Rentals -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<h3 class="text-gray-800 dark:text-white font-semibold mb-3">Recent Rentals</h3>
<div class="space-y-2">
@forelse($recentRentals as $rental)
<a href="{{ route('rentals.show', $rental) }}" class="flex items-center justify-between p-2.5 bg-gray-50 rounded-lg hover:bg-gray-100 transition">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-lg bg-blue-100 flex items-center justify-center">
<i class="fas fa-car text-blue-600 text-xs"></i>
</div>
<div>
<p class="text-gray-800 font-medium text-sm">{{ $rental->car->brand }} {{ $rental->car->model }}</p>
<p class="text-gray-500 text-xs">{{ $rental->customer->name }}</p>
</div>
</div>
<div class="text-right">
<span class="px-1.5 py-0.5 rounded text-xs font-medium
="px-2 {{ $rental->status == 'active' ? 'bg-green-100 text-green-700' :
($rental->status == 'pending' ? 'bg-amber-100 text-amber-700' : 'bg-gray-100 text-gray-600') }}">
{{ $rental->status }}
</span>
</div>
</a>
@empty
<p class="text-gray-500 text-center py-4 text-sm">No rentals yet</p>
@endforelse
</div>
</div>
<!-- Recent Services -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<h3 class="text-gray-800 dark:text-white font-semibold mb-3">Recent Services</h3>
<div class="space-y-2">
@forelse($recentServices as $service)
<a href="{{ route('services.show', $service) }}" class="flex items-center justify-between p-2.5 bg-gray-50 rounded-lg hover:bg-gray-100 transition">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-lg bg-purple-100 flex items-center justify-center">
<i class="fas fa-wrench text-purple-600 text-xs"></i>
</div>
<div>
<p class="text-gray-800 font-medium text-sm">{{ $service->car->brand }} {{ $service->car->model }}</p>
<p class="text-gray-500 text-xs capitalize">{{ str_replace('_', ' ', $service->type) }}</p>
</div>
</div>
<div class="text-right">
<span class="text-gray-800 font-medium text-sm"> BHD {{ number_format($service->cost, 0) }}</span>
</div>
</a>
@empty
<p class="text-gray-500 text-center py-3 text-sm">No services yet</p>
@endforelse
</div>
</div>
</div>
</div>
<script>
// Revenue Chart
const revenueCtx = document.getElementById('revenueChart').getContext('2d');
new Chart(revenueCtx, {
type: 'line',
data: {
labels: {!! json_encode(['5 mo ago', '4 mo ago', '3 mo ago', '2 mo ago', 'Last mo', 'This mo']) !!},
datasets: [{
label: 'Revenue',
data: {!! json_encode($monthlyRevenueChart) !!},
borderColor: '#2563eb',
backgroundColor: 'rgba(37, 99, 235, 0.1)',
fill: true,
tension: 0.4,
pointBackgroundColor: '#2563eb',
pointRadius: 4,
pointHoverRadius: 6
}]
},
options: {
responsive: true,
plugins: { legend: { display: false } },
scales: {
x: { grid: { display: false }, ticks: { color: '#6b7280' } },
y: { grid: { color: '#e5e7eb' }, ticks: { color: '#6b7280', callback: function(v) { return 'BHD ' + v; } } }
}
}
});
// Fleet Chart
const fleetCtx = document.getElementById('fleetChart').getContext('2d');
const fleetChart = new Chart(fleetCtx, {
type: 'doughnut',
data: {
labels: ['Available', 'Rented', 'Maintenance'],
datasets: [{
data: [{!! $carStatusData['available'] !!}, {!! $carStatusData['rented'] !!}, {!! $carStatusData['maintenance'] !!}],
backgroundColor: ['#16a34a', '#f59e0b', '#dc2626'],
borderWidth: 0
}]
},
options: {
responsive: true,
onClick: (evt, elements) => {
if (elements.length > 0) {
const index = elements[0].index;
const statuses = ['available', 'rented', 'maintenance'];
openFleetModal(statuses[index]);
}
},
plugins: {
legend: { position: 'bottom', labels: { color: '#6b7280', padding: 15 } }
}
}
});
// Rentals Chart
const rentalsCtx = document.getElementById('rentalsChart').getContext('2d');
new Chart(rentalsCtx, {
type: 'bar',
data: {
labels: {!! json_encode(['5 mo ago', '4 mo ago', '3 mo ago', '2 mo ago', 'Last mo', 'This mo']) !!},
datasets: [{
label: 'Rentals',
data: {!! json_encode($monthlyRentals) !!},
backgroundColor: '#6366f1',
borderRadius: 4
}]
},
options: {
responsive: true,
plugins: { legend: { display: false } },
scales: {
x: { grid: { display: false }, ticks: { color: '#6b7280' } },
y: { grid: { color: '#e5e7eb' }, ticks: { color: '#6b7280' } }
}
}
});
// Fleet modal data
const carsByStatus = {
available: @json($carsByStatus['available']->toArray()),
rented: @json($carsByStatus['rented']->toArray()),
maintenance: @json($carsByStatus['maintenance']->toArray())
};
function openFleetModal(status = null) {
const modal = document.getElementById('fleetModal');
const title = document.getElementById('modalTitle');
const subtitle = document.getElementById('modalSubtitle');
const list = document.getElementById('modalList');
// If no status provided, show all
if (!status) {
// Show all cars grouped by status
let html = '';
const statusCounts = { available: 0, rented: 0, maintenance: 0 };
['available', 'rented', 'maintenance'].forEach(s => {
const cars = carsByStatus[s];
statusCounts[s] = cars.length;
if (cars.length > 0) {
const colors = { available: 'text-green-600 bg-green-50', rented: 'text-amber-600 bg-amber-50', maintenance: 'text-red-600 bg-red-50' };
const borderColors = { available: 'border-l-green-500', rented: 'border-l-amber-500', maintenance: 'border-l-red-500' };
html += `<h4 class="font-semibold text-gray-700 text-sm uppercase tracking-wide mb-2 mt-4 flex items-center gap-2">
<span class="w-2 h-2 rounded-full ${s === 'available' ? 'bg-green-500' : s === 'rented' ? 'bg-amber-500' : 'bg-red-500'}"></span>
${s} (${cars.length})
</h4>`;
cars.forEach(car => {
html += `<a href="/cars/${car.id}" class="flex items-center justify-between p-3 bg-white border border-gray-100 rounded-lg hover:border-blue-300 hover:shadow-md hover:bg-blue-50/50 transition-all duration-200 group">
<div class="flex items-center gap-3">
<div class="w-9 h-9 rounded-lg ${colors[s]} flex items-center justify-center">
<i class="fas fa-car text-sm"></i>
</div>
<div>
<p class="font-semibold text-gray-800 group-hover:text-blue-700">${car.brand} ${car.model}</p>
<p class="text-xs text-gray-500">${car.year}${car.color}</p>
</div>
</div>
<div class="text-right">
<p class="font-medium text-gray-600 text-sm">${car.license_plate}</p>
<p class="text-xs text-gray-400">${car.daily_rate} BHD/day</p>
</div>
</a>`;
});
}
});
list.innerHTML = html || '<p class="text-gray-500 text-center py-8">No cars found</p>';
title.textContent = 'Complete Fleet';
subtitle.textContent = `${statusCounts.available + statusCounts.rented + statusCounts.maintenance} vehicles total`;
} else {
const cars = carsByStatus[status] || [];
const statusColors = {
available: { bg: 'bg-green-50', icon: 'text-green-600', border: 'border-l-green-500' },
rented: { bg: 'bg-amber-50', icon: 'text-amber-600', border: 'border-l-amber-500' },
maintenance: { bg: 'bg-red-50', icon: 'text-red-600', border: 'border-l-red-500' }
};
const statusLabels = { available: 'Available', rented: 'Rented', maintenance: 'Maintenance' };
const statusIcons = { available: 'fa-check-circle', rented: 'fa-clock', maintenance: 'fa-tools' };
let html = '';
cars.forEach(car => {
const c = statusColors[status];
html += `<a href="/cars/${car.id}" class="flex items-center justify-between p-3 bg-white border border-gray-100 rounded-lg hover:border-blue-300 hover:shadow-md hover:bg-blue-50/50 transition-all duration-200 group">
<div class="flex items-center gap-3">
<div class="w-9 h-9 rounded-lg ${c.bg} flex items-center justify-center">
<i class="fas ${statusIcons[status]} ${c.icon} text-sm"></i>
</div>
<div>
<p class="font-semibold text-gray-800 group-hover:text-blue-700">${car.brand} ${car.model}</p>
<p class="text-xs text-gray-500">${car.year}${car.color}</p>
</div>
</div>
<div class="text-right">
<p class="font-medium text-gray-600 text-sm">${car.license_plate}</p>
<p class="text-xs text-gray-400">${car.daily_rate} BHD/day</p>
</div>
</a>`;
});
list.innerHTML = html || `<div class="text-center py-8">
<div class="w-16 h-16 rounded-full bg-gray-100 flex items-center justify-center mx-auto mb-3">
<i class="fas fa-car text-gray-400 text-2xl"></i>
</div>
<p class="text-gray-500">No cars in this status</p>
</div>`;
title.textContent = statusLabels[status] || status;
subtitle.textContent = `${cars.length} vehicle${cars.length !== 1 ? 's' : ''}`;
}
modal.classList.remove('hidden');
}
function closeFleetModal() {
document.getElementById('fleetModal').classList.add('hidden');
}
</script>
<!-- Fleet Modal -->
<div id="fleetModal" class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm hidden z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl shadow-2xl max-w-lg w-full max-h-[85vh] overflow-hidden transform transition-all">
<!-- Modal Header -->
<div class="relative bg-gradient-to-r from-slate-800 to-slate-700 px-6 py-5">
<div class="flex justify-between items-center">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-xl bg-white/20 flex items-center justify-center">
<i class="fas fa-car text-white text-lg"></i>
</div>
<div>
<h3 id="modalTitle" class="text-xl font-bold text-white">Fleet Status</h3>
<p class="text-slate-300 text-xs" id="modalSubtitle">Vehicle Details</p>
</div>
</div>
<button onclick="closeFleetModal()" class="w-8 h-8 rounded-lg bg-white/10 text-white hover:bg-white/20 flex items-center justify-center transition">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- Modal Body -->
<div id="modalList" class="p-4 overflow-y-auto max-h-[55vh] space-y-2">
</div>
<!-- Modal Footer -->
<div class="px-6 py-4 bg-gray-50 border-t border-gray-100">
<p class="text-center text-xs text-gray-400">Click on a car to view full details</p>
</div>
</div>
</div>
<!-- Quick Rent Modal -->
<div id="quickRentModal" style="display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(15, 23, 42, 0.6); z-index: 9999; align-items: center; justify-content: center; padding: 16px;">
<div style="background: white; border-radius: 16px; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); max-width: 672px; width: 100%; max-height: 90vh; overflow: hidden; display: flex; flex-direction: column;">
<!-- Header -->
<div style="background: linear-gradient(to right, #f59e0b, #ea580c); padding: 20px 24px; border-radius: 16px 16px 0 0;">
<div class="flex justify-between items-center">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-xl bg-white/20 flex items-center justify-center">
<i class="fas fa-bolt text-white text-lg"></i>
</div>
<div>
<h3 class="text-xl font-bold text-white">Quick Rent</h3>
<p class="text-amber-100 text-xs">Complete rental in minutes</p>
</div>
</div>
<button onclick="closeQuickRentModal()" class="w-8 h-8 rounded-lg bg-white/10 text-white hover:bg-white/20 flex items-center justify-center transition">
<i class="fas fa-times"></i>
</button>
</div>
<!-- Steps -->
<div class="flex justify-center mt-4">
<div class="flex items-center gap-2">
<div id="stepIndicator1" class="step-dot active"></div>
<div class="step-line"></div>
<div id="stepIndicator2" class="step-dot"></div>
<div class="step-line"></div>
<div id="stepIndicator3" class="step-dot"></div>
<div class="step-line"></div>
<div id="stepIndicator4" class="step-dot"></div>
</div>
</div>
</div>
<!-- Body -->
<div style="padding: 24px; overflow-y: auto; flex: 1;">
<!-- Step 1: Customer -->
<div id="step1" class="step-content">
<h4 class="text-lg font-semibold text-gray-800 mb-4">Select or Create Customer</h4>
<!-- Existing Customer -->
<div class="mb-4">
<label class="flex items-center gap-2 cursor-pointer mb-3">
<input type="radio" name="customerType" value="existing" checked onchange="toggleCustomerForm()" class="w-4 h-4 text-amber-500">
<span class="text-gray-700 font-medium">Existing Customer</span>
</label>
<!-- Searchable Dropdown -->
<div class="relative">
<input type="text" id="customerSearch" onkeyup="filterCustomers()" onfocus="showCustomerDropdown()" onblur="setTimeout(() => hideCustomerDropdown(), 200)"
placeholder="Search by name, phone, or email..."
class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<div id="customerDropdown" style="display: none; position: absolute; z-index: 99999; width: 100%; margin-top: 4px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); max-height: 192px; overflow-y: auto;">
<div id="customerList"></div>
</div>
<input type="hidden" id="selectedCustomerId" value="">
</div>
<p id="selectedCustomerInfo" style="margin-top: 8px; font-size: 14px; color: #16a34a; display: none;">
<i class="fas fa-check-circle"></i> <span id="selectedCustomerName"></span> selected
</p>
</div>
<!-- New Customer -->
<div>
<label class="flex items-center gap-2 cursor-pointer mb-3">
<input type="radio" name="customerType" value="new" onchange="toggleCustomerForm()" class="w-4 h-4 text-amber-500">
<span class="text-gray-700 font-medium">New Customer</span>
</label>
<div id="newCustomerForm" class="hidden grid grid-cols-2 gap-3">
<input type="text" id="newCustomerName" placeholder="Full Name" class="px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<input type="email" id="newCustomerEmail" placeholder="Email" class="px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<input type="text" id="newCustomerPhone" placeholder="Phone" class="px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<input type="text" id="newCustomerLicense" placeholder="License Number" class="px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<input type="date" id="newCustomerLicenseExpiry" class="px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<input type="date" id="newCustomerDob" class="px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<input type="text" id="newCustomerAddress" placeholder="Address" class="px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500 col-span-2">
</div>
</div>
</div>
<!-- Step 2: Car -->
<div id="step2" class="step-content hidden">
<h4 class="text-lg font-semibold text-gray-800 mb-4">Select Vehicle</h4>
<!-- Searchable Car Dropdown -->
<div class="relative">
<input type="text" id="carSearch" onkeyup="filterCars()" onfocus="showCarDropdown()" onblur="setTimeout(() => hideCarDropdown(), 200)"
placeholder="Search by make, model, or plate..."
class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<div id="carDropdown" style="display: none; position: absolute; z-index: 99999; width: 100%; margin-top: 4px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); max-height: 192px; overflow-y: auto;">
<div id="carList"></div>
</div>
<input type="hidden" id="selectedCarId" value="">
<p id="selectedCarInfo" style="margin-top: 8px; font-size: 14px; color: #16a34a; display: none;">
<i class="fas fa-check-circle"></i> <span id="selectedCarName"></span> selected
</p>
</div>
<div id="selectedCarDetails" class="mt-4 p-4 bg-gray-50 rounded-lg hidden">
<div class="flex justify-between items-center">
<div>
<p id="carDisplayName" class="font-semibold text-gray-800"></p>
<p id="carDisplayDetails" class="text-sm text-gray-500"></p>
</div>
<p id="carDisplayRate" class="text-xl font-bold text-amber-600"></p>
</div>
</div>
</div>
<!-- Step 3: Rental Period -->
<div id="step3" class="step-content hidden">
<h4 class="text-lg font-semibold text-gray-800 mb-4">Rental Period</h4>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Rental Type</label>
<select id="rentalType" onchange="calculateRentalPrice()" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<option value="daily" data-days="1">Daily</option>
<option value="weekly" data-days="7">Weekly</option>
<option value="monthly" data-days="30">Monthly</option>
<option value="lease" data-days="365">Lease (1 Year)</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Start Date</label>
<input type="date" id="rentalStartDate" onchange="calculateRentalPrice()" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Pickup Time</label>
<input type="time" id="rentalPickupTime" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">End Date</label>
<input type="date" id="rentalEndDate" onchange="calculateRentalPrice()" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Return Time</label>
<input type="time" id="rentalReturnTime" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
</div>
<!-- Price Summary -->
<div class="mt-6 p-4 bg-gradient-to-r from-amber-50 to-orange-50 rounded-xl border border-amber-200">
<div class="flex justify-between items-center mb-2">
<span class="text-gray-600">Rental Amount</span>
<span id="rentalAmount" class="font-semibold text-gray-800">0.00 BHD</span>
</div>
<div class="flex justify-between items-center mb-2">
<span class="text-gray-600">Discount</span>
<span id="rentalDiscount" class="text-green-600 font-medium">0%</span>
</div>
<div class="flex justify-between items-center mb-2">
<span class="text-gray-600">Advance Payment (50%)</span>
<span id="rentalAdvance" class="font-semibold text-amber-600">0.00 BHD</span>
</div>
<div class="border-t border-amber-200 mt-3 pt-3 flex justify-between items-center">
<span class="font-semibold text-gray-800">Total</span>
<span id="rentalTotal" class="text-2xl font-bold text-amber-600">0.00 BHD</span>
</div>
</div>
</div>
<!-- Step 4: Confirm & Payment -->
<div id="step4" class="step-content hidden">
<h4 class="text-lg font-semibold text-gray-800 mb-4">Confirm & Payment</h4>
<!-- Summary -->
<div class="p-4 bg-gray-50 rounded-lg mb-4">
<h5 class="font-medium text-gray-700 mb-3">Rental Summary</h5>
<div class="space-y-2 text-sm">
<div class="flex justify-between">
<span class="text-gray-500">Customer:</span>
<span id="summaryCustomer" class="font-medium text-gray-800">-</span>
</div>
<div class="flex justify-between">
<span class="text-gray-500">Vehicle:</span>
<span id="summaryCar" class="font-medium text-gray-800">-</span>
</div>
<div class="flex justify-between">
<span class="text-gray-500">Period:</span>
<span id="summaryPeriod" class="font-medium text-gray-800">-</span>
</div>
<div class="flex justify-between">
<span class="text-gray-500">Type:</span>
<span id="summaryType" class="font-medium text-gray-800 capitalize">-</span>
</div>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Advance Payment</label>
<input type="number" id="advancePayment" step="0.01" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Payment Method</label>
<select id="paymentMethod" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500">
<option value="cash">Cash</option>
<option value="card">Card</option>
<option value="bank_transfer">Bank Transfer</option>
<option value="online">Online</option>
</select>
</div>
</div>
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Notes (Optional)</label>
<textarea id="rentalNotes" rows="2" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-amber-500"></textarea>
</div>
<!-- Digital Signature -->
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Customer Signature</label>
<div style="border: 2px dashed #d1d5db; border-radius: 8px; padding: 8px; background: #fafafa;">
<canvas id="signaturePad" width="400" height="120" style="width: 100%; height: 120px; border-radius: 4px; cursor: crosshair; background: white; touch-action: none;"></canvas>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 8px;">
<button type="button" onclick="clearSignature()" style="padding: 6px 12px; font-size: 12px; border-radius: 6px; border: 1px solid #d1d5db; background: white; color: #6b7280; cursor: pointer;">
<i class="fas fa-eraser"></i> Clear
</button>
<span style="font-size: 12px; color: #9ca3af;">Sign above to confirm</span>
</div>
<input type="hidden" id="customerSignature" value="">
</div>
</div>
<!-- Success -->
<div id="stepSuccess" class="hidden text-center py-8">
<div class="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fas fa-check text-green-500 text-4xl"></i>
</div>
<h4 class="text-xl font-semibold text-gray-800 mb-2">Rental Created Successfully!</h4>
<p class="text-gray-500 mb-6">Contract has been generated and is ready for download.</p>
<div class="flex justify-center gap-3">
<a id="downloadContract" href="#" target="_blank" class="flex items-center gap-2 bg-amber-500 text-white px-6 py-3 rounded-lg hover:bg-amber-600 font-medium">
<i class="fas fa-file-pdf"></i> Download Contract
</a>
<button onclick="closeQuickRentModal()" class="flex items-center gap-2 bg-gray-100 text-gray-700 px-6 py-3 rounded-lg hover:bg-gray-200 font-medium">
Done
</button>
</div>
</div>
</div>
<!-- Footer -->
<div id="quickRentFooter" style="padding: 16px 24px; background: #f9fafb; border-top: 1px solid #e5e7eb; display: flex; justify-content: space-between; align-items: center;">
<button id="prevBtn" onclick="prevStep()" style="padding: 8px 16px; border-radius: 8px; color: #6b7280; background: transparent; font-weight: 500; display: none;">Back</button>
<div style="flex: 1;"></div>
<button id="nextBtn" onclick="nextStep()" style="padding: 8px 24px; border-radius: 8px; background: #f59e0b; color: white; font-weight: 500;">Next</button>
</div>
</div>
</div>
<style>
.step-dot { width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,0.3); }
.step-dot.active { background: white; transform: scale(1.2); }
.step-line { width: 30px; height: 2px; background: rgba(255,255,255,0.3); }
</style>
<script>
let currentStep = 1;
const totalSteps = 4;
let selectedCustomerId = null;
let selectedCarId = null;
let newCustomerId = null;
let totalAmount = 0;
let finalRentalId = null;
// Pricing
const pricing = { daily: 1, weekly: 0.9, monthly: 0.8, lease: 0.7 };
let allCustomers = [];
// Initialize
document.addEventListener('DOMContentLoaded', function() {
loadCustomers();
loadCars();
});
function openQuickRentModal() {
document.getElementById('quickRentModal').style.display = 'flex';
currentStep = 1;
updateStepUI();
setTimeout(initSignaturePad, 100);
}
function closeQuickRentModal() {
document.getElementById('quickRentModal').style.display = 'none';
resetQuickRentForm();
}
function resetQuickRentForm() {
currentStep = 1;
selectedCustomerId = null;
selectedCarId = null;
selectedCarRate = 0;
newCustomerId = null;
totalAmount = 0;
document.querySelectorAll('#step1, #step2, #step3, #step4').forEach(s => s.classList.add('hidden'));
document.getElementById('stepSuccess').classList.add('hidden');
document.getElementById('quickRentFooter').classList.remove('hidden');
document.querySelector('input[name="customerType"][value="existing"]').checked = true;
toggleCustomerForm();
updateStepUI();
// Reset customer search
document.getElementById('customerSearch').value = '';
document.getElementById('selectedCustomerId').value = '';
document.getElementById('selectedCustomerInfo').style.display = 'none';
// Reset car search
document.getElementById('carSearch').value = '';
document.getElementById('selectedCarId').value = '';
document.getElementById('selectedCarInfo').style.display = 'none';
document.getElementById('selectedCarDetails').style.display = 'none';
// Clear signature
clearSignature();
}
function toggleCustomerForm() {
const isNew = document.querySelector('input[name="customerType"]:checked').value === 'new';
document.getElementById('newCustomerForm').classList.toggle('hidden', !isNew);
document.getElementById('customerSearch').parentElement.classList.toggle('hidden', isNew);
}
// Searchable Customer Dropdown Functions
async function loadCustomers() {
const response = await fetch('/quick-rental/customers');
allCustomers = await response.json();
renderCustomerList(allCustomers);
}
function renderCustomerList(customers) {
const list = document.getElementById('customerList');
if (customers.length === 0) {
list.innerHTML = '<div class="px-4 py-3 text-gray-500 text-sm">No customers found</div>';
return;
}
let html = '';
customers.forEach(c => {
html += `<div onclick="selectCustomer(${c.id}, '${c.name}', '${c.phone}', '${c.email}')"
class="px-4 py-3 hover:bg-amber-50 cursor-pointer border-b border-gray-100 last:border-0">
<div class="flex justify-between items-start">
<div>
<p class="font-medium text-gray-800">${c.name}</p>
<p class="text-sm text-gray-500">${c.phone} • ${c.email}</p>
</div>
<span class="text-xs bg-green-100 text-green-700 px-2 py-1 rounded-full">Active</span>
</div>
</div>`;
});
list.innerHTML = html;
}
function filterCustomers() {
const search = document.getElementById('customerSearch').value.toLowerCase();
const filtered = allCustomers.filter(c =>
c.name.toLowerCase().includes(search) ||
c.phone.toLowerCase().includes(search) ||
c.email.toLowerCase().includes(search)
);
renderCustomerList(filtered);
}
function showCustomerDropdown() {
// Move dropdown outside modal to avoid overflow clipping
const dropdown = document.getElementById('customerDropdown');
dropdown.style.display = 'block';
dropdown.style.position = 'fixed';
const input = document.getElementById('customerSearch');
const rect = input.getBoundingClientRect();
dropdown.style.left = rect.left + 'px';
dropdown.style.top = (rect.bottom + 5) + 'px';
dropdown.style.width = rect.width + 'px';
dropdown.style.zIndex = '999999';
filterCustomers();
}
function hideCustomerDropdown() {
document.getElementById('customerDropdown').style.display = 'none';
}
function selectCustomer(id, name, phone, email) {
selectedCustomerId = id;
document.getElementById('selectedCustomerId').value = id;
document.getElementById('customerSearch').value = `${name} - ${phone}`;
document.getElementById('selectedCustomerName').textContent = name;
document.getElementById('selectedCustomerInfo').style.display = 'block';
hideCustomerDropdown();
}
let allCars = [];
async function loadCars() {
const response = await fetch('/quick-rental/cars');
allCars = await response.json();
renderCarList(allCars);
}
function renderCarList(cars) {
const list = document.getElementById('carList');
if (cars.length === 0) {
list.innerHTML = '<div class="px-4 py-3 text-gray-500 text-sm">No cars found</div>';
return;
}
let html = '';
cars.forEach(c => {
html += `<div onclick="selectCar(${c.id}, '${c.brand}', '${c.model}', '${c.license_plate}', ${c.daily_rate}, '${c.year}', '${c.color}')"
class="px-4 py-3 hover:bg-amber-50 cursor-pointer border-b border-gray-100 last:border-0">
<div class="flex justify-between items-start">
<div>
<p class="font-medium text-gray-800">${c.brand} ${c.model}</p>
<p class="text-sm text-gray-500">${c.year} • ${c.color}</p>
</div>
<div class="text-right">
<p class="font-semibold text-amber-600">${c.daily_rate} BHD/day</p>
<p class="text-xs text-gray-500">${c.license_plate}</p>
</div>
</div>
</div>`;
});
list.innerHTML = html;
}
function filterCars() {
const search = document.getElementById('carSearch').value.toLowerCase();
const filtered = allCars.filter(c =>
c.brand.toLowerCase().includes(search) ||
c.model.toLowerCase().includes(search) ||
c.license_plate.toLowerCase().includes(search)
);
renderCarList(filtered);
}
function showCarDropdown() {
// Move dropdown outside modal to avoid overflow clipping
const dropdown = document.getElementById('carDropdown');
dropdown.style.display = 'block';
dropdown.style.position = 'fixed';
const input = document.getElementById('carSearch');
const rect = input.getBoundingClientRect();
dropdown.style.left = rect.left + 'px';
dropdown.style.top = (rect.bottom + 5) + 'px';
dropdown.style.width = rect.width + 'px';
dropdown.style.zIndex = '999999';
filterCars();
}
function hideCarDropdown() {
document.getElementById('carDropdown').style.display = 'none';
}
function selectCar(id, brand, model, plate, rate, year, color) {
selectedCarId = id;
document.getElementById('selectedCarId').value = id;
document.getElementById('carSearch').value = `${brand} ${model} - ${plate}`;
document.getElementById('selectedCarName').textContent = `${brand} ${model}`;
// Show selected info
document.getElementById('selectedCarInfo').style.display = 'block';
document.getElementById('selectedCarDetails').style.display = 'block';
document.getElementById('carDisplayName').textContent = `${brand} ${model}`;
document.getElementById('carDisplayDetails').textContent = `${year} • ${color} • ${plate}`;
document.getElementById('carDisplayRate').textContent = `${rate} BHD/day`;
// Store rate for calculation
selectedCarRate = rate;
hideCarDropdown();
calculateRentalPrice();
}
let selectedCarRate = 0;
// Signature Pad - Initialize after DOM loads
let signatureCanvas, signatureCtx, isDrawing;
function initSignaturePad() {
signatureCanvas = document.getElementById('signaturePad');
if (!signatureCanvas) return;
signatureCtx = signatureCanvas.getContext('2d');
isDrawing = false;
signatureCanvas.addEventListener('mousedown', function(e) {
isDrawing = true;
signatureCtx.beginPath();
const rect = signatureCanvas.getBoundingClientRect();
const scaleX = signatureCanvas.width / rect.width;
const scaleY = signatureCanvas.height / rect.height;
signatureCtx.moveTo((e.clientX - rect.left) * scaleX, (e.clientY - rect.top) * scaleY);
signatureCtx.strokeStyle = '#1f2937';
signatureCtx.lineWidth = 2;
signatureCtx.lineCap = 'round';
});
signatureCanvas.addEventListener('mousemove', function(e) {
if (!isDrawing) return;
const rect = signatureCanvas.getBoundingClientRect();
const scaleX = signatureCanvas.width / rect.width;
const scaleY = signatureCanvas.height / rect.height;
signatureCtx.lineTo((e.clientX - rect.left) * scaleX, (e.clientY - rect.top) * scaleY);
signatureCtx.stroke();
});
signatureCanvas.addEventListener('mouseup', function() { isDrawing = false; });
signatureCanvas.addEventListener('mouseout', function() { isDrawing = false; });
}
function clearSignature() {
if (!signatureCanvas) return;
signatureCtx.clearRect(0, 0, signatureCanvas.width, signatureCanvas.height);
}
function calculateRentalPrice() {
const dailyRate = selectedCarRate || 0;
const rentalType = document.getElementById('rentalType');
const typeOption = rentalType.options[rentalType.selectedIndex];
const days = parseInt(typeOption.dataset.days) || 1;
const startDate = document.getElementById('rentalStartDate').value;
const endDate = document.getElementById('rentalEndDate').value;
let total = 0;
let displayDays = days;
if (startDate && endDate) {
const start = new Date(startDate);
const end = new Date(endDate);
const diffTime = Math.abs(end - start);
displayDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
}
const multiplier = pricing[rentalType.value];
total = dailyRate * displayDays * multiplier;
totalAmount = total;
document.getElementById('rentalAmount').textContent = (dailyRate * displayDays).toFixed(3) + ' BHD';
document.getElementById('rentalDiscount').textContent = Math.round((1 - multiplier) * 100) + '%';
document.getElementById('rentalAdvance').textContent = (total * 0.5).toFixed(3) + ' BHD';
document.getElementById('rentalTotal').textContent = total.toFixed(3) + ' BHD';
document.getElementById('advancePayment').value = (total * 0.5).toFixed(2);
}
function updateStepUI() {
// Update step indicators
for (let i = 1; i <= totalSteps; i++) {
const dot = document.getElementById('stepIndicator' + i);
if (i <= currentStep) dot.classList.add('active');
else dot.classList.remove('active');
}
// Show/hide steps
for (let i = 1; i <= totalSteps; i++) {
document.getElementById('step' + i).classList.toggle('hidden', i !== currentStep);
}
// Buttons
document.getElementById('prevBtn').classList.toggle('hidden', currentStep === 1);
document.getElementById('nextBtn').textContent = currentStep === totalSteps ? 'Create Rental' : 'Next';
// Hide footer on success
if (document.getElementById('stepSuccess').classList.contains('hidden') === false) {
document.getElementById('quickRentFooter').classList.add('hidden');
}
}
async function nextStep() {
console.log('Step:', currentStep);
if (currentStep === 1) {
// Validate customer
const isNew = document.querySelector('input[name="customerType"]:checked').value === 'new';
console.log('Customer type:', isNew);
if (isNew) {
// Create new customer
const customerData = {
name: document.getElementById('newCustomerName').value,
email: document.getElementById('newCustomerEmail').value,
phone: document.getElementById('newCustomerPhone').value,
license_number: document.getElementById('newCustomerLicense').value,
license_expiry: document.getElementById('newCustomerLicenseExpiry').value,
dob: document.getElementById('newCustomerDob').value,
address: document.getElementById('newCustomerAddress').value,
status: 'active'
};
if (!customerData.name || !customerData.phone || !customerData.email) {
alert('Please fill in all customer fields');
return;
}
const response = await fetch('/customers', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
body: JSON.stringify(customerData)
});
const result = await response.json();
newCustomerId = result.id;
selectedCustomerId = result.id;
} else {
selectedCustomerId = document.getElementById('selectedCustomerId').value;
}
console.log('Selected customer:', selectedCustomerId, 'New:', newCustomerId);
if (!selectedCustomerId && !newCustomerId) {
alert('Please select or create a customer');
return;
}
}
if (currentStep === 2) {
selectedCarId = document.getElementById('selectedCarId').value;
console.log('Selected car:', selectedCarId);
if (!selectedCarId) {
alert('Please select a car');
return;
}
// Show car info - already shown in selectCar function
}
if (currentStep === 3) {
console.log('Checking dates');
if (!document.getElementById('rentalStartDate').value || !document.getElementById('rentalEndDate').value) {
alert('Please select rental dates');
return;
}
// Update summary
document.getElementById('summaryCustomer').textContent = document.querySelector('input[name="customerType"]:checked').value === 'new'
? document.getElementById('newCustomerName').value
: document.getElementById('customerSearch').value;
document.getElementById('summaryCar').textContent = document.getElementById('carSearch').value;
document.getElementById('summaryPeriod').textContent = document.getElementById('rentalStartDate').value + ' to ' + document.getElementById('rentalEndDate').value;
document.getElementById('summaryType').textContent = document.getElementById('rentalType').value;
}
if (currentStep === totalSteps) {
await createRental();
return;
}
currentStep++;
updateStepUI();
}
function prevStep() {
if (currentStep > 1) {
currentStep--;
updateStepUI();
}
}
async function createRental() {
// Get signature data
const signatureData = signatureCanvas ? signatureCanvas.toDataURL('image/png') : '';
const data = {
customer_id: selectedCustomerId || newCustomerId,
car_id: selectedCarId,
rental_type: document.getElementById('rentalType').value,
start_date: document.getElementById('rentalStartDate').value,
pickup_time: document.getElementById('rentalPickupTime').value,
end_date: document.getElementById('rentalEndDate').value,
return_time: document.getElementById('rentalReturnTime').value,
total_amount: totalAmount,
advance_payment: parseFloat(document.getElementById('advancePayment').value) || 0,
payment_method: document.getElementById('paymentMethod').value,
notes: document.getElementById('rentalNotes').value,
customer_signature: signatureData
};
const response = await fetch('/quick-rental/store', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
body: JSON.stringify(data)
});
const result = await response.json();
finalRentalId = result.rental_id;
// Show success
document.getElementById('step4').classList.add('hidden');
document.getElementById('stepSuccess').classList.remove('hidden');
document.getElementById('quickRentFooter').classList.add('hidden');
document.getElementById('downloadContract').href = '/quick-rental/contract/' + finalRentalId;
}
</script>
</body>
</html>