MIF_E31221305/TA_website/resources/views/admin/dashboard.blade.php

315 lines
16 KiB
PHP

@extends('admin.layouts.app')
@section('title', 'Dashboard')
@section('content')
<div class="p-6">
<!-- Error Alert -->
<div id="error-alert" class="hidden mb-6">
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<strong class="font-bold">Error!</strong>
<span id="error-message" class="block sm:inline"></span>
</div>
</div>
<!-- Summary Cards -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 mb-6">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 bg-blue-100 rounded-full">
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
</svg>
</div>
<div class="ml-4">
<h2 class="text-gray-600 text-sm">Total Penjahit</h2>
<p class="text-2xl font-semibold text-gray-800" id="total-penjahit">-</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 bg-green-100 rounded-full">
<svg class="w-6 h-6 text-green-600" 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 class="ml-4">
<h2 class="text-gray-600 text-sm">Total Pelanggan</h2>
<p class="text-2xl font-semibold text-gray-800" id="total-pelanggan">-</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 bg-purple-100 rounded-full">
<svg class="w-6 h-6 text-purple-600" 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 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
</svg>
</div>
<div class="ml-4">
<h2 class="text-gray-600 text-sm">Total Pesanan</h2>
<p class="text-2xl font-semibold text-gray-800" id="total-bookings">-</p>
</div>
</div>
</div>
{{-- <div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 bg-yellow-100 rounded-full">
<svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
<div class="ml-4">
<h2 class="text-gray-600 text-sm">Total Layanan</h2>
<p class="text-2xl font-semibold text-gray-800" id="total-services">-</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 bg-red-100 rounded-full">
<svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"></path>
</svg>
</div>
<div class="ml-4">
<h2 class="text-gray-600 text-sm">Rating Rata-rata</h2>
<p class="text-2xl font-semibold text-gray-800" id="average-rating">-</p>
</div>
</div>
</div> --}}
</div>
<!-- Booking Statistics -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<div class="bg-white rounded-lg shadow p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">Status Pesanan</h2>
<div class="space-y-4" id="booking-status">
<!-- Status pesanan akan ditampilkan di sini -->
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">Statistik Bulan Ini</h2>
<div class="space-y-4" id="monthly-stats">
<div class="flex items-center justify-between p-4 bg-blue-50 rounded-lg">
<div class="flex items-center">
<div class="w-3 h-3 rounded-full bg-blue-500 mr-2"></div>
<span class="text-gray-600">Total Pesanan</span>
</div>
<span class="font-semibold text-blue-600" id="total-monthly-orders">-</span>
</div>
<div class="flex items-center justify-between p-4 bg-green-50 rounded-lg">
<div class="flex items-center">
<div class="w-3 h-3 rounded-full bg-green-500 mr-2"></div>
<span class="text-gray-600">Pesanan Selesai</span>
</div>
<span class="font-semibold text-green-600" id="completed-monthly-orders">-</span>
</div>
<div class="flex items-center justify-between p-4 bg-yellow-50 rounded-lg">
<div class="flex items-center">
<div class="w-3 h-3 rounded-full bg-yellow-500 mr-2"></div>
<span class="text-gray-600">Tingkat Penyelesaian</span>
</div>
<span class="font-semibold text-yellow-600" id="completion-rate">-</span>
</div>
</div>
</div>
</div>
<!-- Recent Bookings and Top Tailors -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<div class="bg-white rounded-lg shadow">
<div class="p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">Pesanan Terbaru</h2>
<div class="overflow-x-auto">
<table class="min-w-full">
<thead>
<tr class="border-b">
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">ID</th>
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">Pelanggan</th>
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">Penjahit</th>
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">Status</th>
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">Tanggal</th>
</tr>
</thead>
<tbody id="recent-bookings">
<!-- Recent bookings akan ditampilkan di sini -->
</tbody>
</table>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">Penjahit Teratas</h2>
<div class="space-y-4" id="top-tailors">
<!-- Top tailors akan ditampilkan di sini -->
</div>
</div>
</div>
</div>
<!-- Recent Users -->
<div class="bg-white rounded-lg shadow">
<div class="p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">Pengguna Terbaru</h2>
<div class="overflow-x-auto">
<table class="min-w-full">
<thead>
<tr class="border-b">
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">ID</th>
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">Nama</th>
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">Role</th>
<th class="text-left py-3 px-4 text-sm font-medium text-gray-600">Tanggal Daftar</th>
</tr>
</thead>
<tbody id="recent-users">
<!-- Recent users akan ditampilkan di sini -->
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Include Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', async function() {
try {
// Get token from session
const token = '{{ session('api_token') }}';
const tokenType = '{{ session('token_type') }}';
if (!token) {
window.location.href = '{{ route('admin.login') }}';
return;
}
const response = await fetch(window.apiUrl('api/admin/dashboard'), {
headers: {
'Authorization': `${tokenType} ${token}`,
'Accept': 'application/json'
}
});
if (!response.ok) {
if (response.status === 401) {
// Unauthorized - redirect to login
window.location.href = '{{ route('admin.login') }}';
return;
}
throw new Error('Failed to fetch dashboard data');
}
const data = await response.json();
if (data.status === 'success') {
// Update summary cards
document.getElementById('total-penjahit').textContent = data.data.summary.total_penjahit;
document.getElementById('total-pelanggan').textContent = data.data.summary.total_pelanggan;
document.getElementById('total-bookings').textContent = data.data.summary.total_bookings;
// document.getElementById('total-services').textContent = data.data.summary.total_services;
// document.getElementById('average-rating').textContent = data.data.summary.average_rating.toFixed(1);
// Update booking status
const statusColors = {
'reservasi': 'blue',
'diproses': 'yellow',
'selesai': 'green'
};
const bookingStatusHtml = Object.entries(data.data.booking_statistics.by_status)
.map(([status, count]) => `
<div class="flex items-center justify-between">
<div class="flex items-center">
<div class="w-3 h-3 rounded-full bg-${statusColors[status]}-500 mr-2"></div>
<span class="text-gray-600 capitalize">${status}</span>
</div>
<span class="font-semibold">${count}</span>
</div>
`).join('');
document.getElementById('booking-status').innerHTML = bookingStatusHtml;
// Update recent bookings
const recentBookingsHtml = data.data.recent_bookings.map(booking => `
<tr class="border-b hover:bg-gray-50">
<td class="py-3 px-4">#${booking.id}</td>
<td class="py-3 px-4">${booking.customer_name}</td>
<td class="py-3 px-4">${booking.tailor_name}</td>
<td class="py-3 px-4">
<span class="px-2 py-1 text-xs rounded-full capitalize
${booking.status === 'reservasi' ? 'bg-blue-100 text-blue-800' : ''}
${booking.status === 'diproses' ? 'bg-yellow-100 text-yellow-800' : ''}
${booking.status === 'selesai' ? 'bg-green-100 text-green-800' : ''}">
${booking.status}
</span>
</td>
<td class="py-3 px-4">${new Date(booking.created_at).toLocaleDateString('id-ID')}</td>
</tr>
`).join('');
document.getElementById('recent-bookings').innerHTML = recentBookingsHtml;
// Update top tailors
const topTailorsHtml = data.data.top_tailors.map(tailor => `
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
<div>
<h3 class="font-semibold text-gray-800">${tailor.name}</h3>
<div class="flex items-center mt-1">
<span class="text-yellow-500">★</span>
<span class="text-sm text-gray-600 ml-1">${tailor.average_rating.toFixed(1)} (${tailor.total_ratings} ulasan)</span>
</div>
</div>
<div class="text-right">
<p class="text-sm text-gray-600">Total Pesanan</p>
<p class="font-semibold text-gray-800">${tailor.total_bookings}</p>
</div>
</div>
`).join('');
document.getElementById('top-tailors').innerHTML = topTailorsHtml;
// Update recent users
const recentUsersHtml = data.data.recent_users.map(user => `
<tr class="border-b hover:bg-gray-50">
<td class="py-3 px-4">#${user.id}</td>
<td class="py-3 px-4">${user.name}</td>
<td class="py-3 px-4">
<span class="px-2 py-1 text-xs rounded-full capitalize
${user.role === 'penjahit' ? 'bg-purple-100 text-purple-800' : ''}
${user.role === 'pelanggan' ? 'bg-green-100 text-green-800' : ''}">
${user.role}
</span>
</td>
<td class="py-3 px-4">${new Date(user.created_at).toLocaleDateString('id-ID')}</td>
</tr>
`).join('');
document.getElementById('recent-users').innerHTML = recentUsersHtml;
// Update monthly statistics
const monthlyData = data.data.booking_statistics.monthly[0];
document.getElementById('total-monthly-orders').textContent = monthlyData.total_bookings;
document.getElementById('completed-monthly-orders').textContent = monthlyData.completed_bookings;
const completionRate = ((monthlyData.completed_bookings / monthlyData.total_bookings) * 100) || 0;
document.getElementById('completion-rate').textContent = `${completionRate.toFixed(1)}%`;
} else {
throw new Error(data.message || 'Failed to load dashboard data');
}
} catch (error) {
console.error('Error:', error);
const errorAlert = document.getElementById('error-alert');
const errorMessage = document.getElementById('error-message');
errorAlert.classList.remove('hidden');
errorMessage.textContent = error.message || 'Terjadi kesalahan saat memuat data dashboard';
}
});
</script>
@endsection