feat(analitik) : membuat fitur analitik untuk barber
This commit is contained in:
parent
9dd4e63f4b
commit
48f3a53343
@ -24,14 +24,28 @@ public function index(): View
|
||||
$totalPayroll = Payroll::query()->barbershop()->sum('total');
|
||||
$totalShaving = Transaction::query()->barbershop()->count();
|
||||
|
||||
$topService = Service::query()->barbershop()->withCount('transactions')->get();
|
||||
|
||||
$paymentMethod = Transaction::select('payment_method', DB::raw('SUM(total) as total_amount'))
|
||||
$topService = Service::query()
|
||||
->barbershop()
|
||||
->groupBy('payment_method')
|
||||
->withCount(['transactions' => function ($query) {
|
||||
$query->when(auth()->user()->role_id === 5, function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
});
|
||||
}])
|
||||
->when(auth()->user()->role_id === 5, function ($query) {
|
||||
$query->whereHas('transactions', function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
});
|
||||
})
|
||||
->get();
|
||||
|
||||
$incomeByBarber = User::with('biography')->barbershop()->barber()->withSum('transactions', 'total')->get();
|
||||
$paymentMethod = Transaction::query()
|
||||
->select('payment_method', DB::raw('SUM(total) as total_amount'))
|
||||
->barbershop()
|
||||
->when(auth()->user()->role_id === 5, function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
})
|
||||
->groupBy('payment_method')
|
||||
->get();
|
||||
|
||||
$transactionByBarber = User::with('biography')->barbershop()->barber()->withCount('transactions')->get();
|
||||
|
||||
@ -47,6 +61,43 @@ public function index(): View
|
||||
$totalUser = User::query()->barbershop()->count();
|
||||
$totalBarber = User::query()->barbershop()->barber()->count();
|
||||
|
||||
$topCustomersByTotal = Transaction::groupBy('customer_id')
|
||||
->select(
|
||||
'customer_id',
|
||||
DB::raw('SUM(total) as total_transaction'),
|
||||
DB::raw('COUNT(*) as transaction_count')
|
||||
)
|
||||
->orderBy('total_transaction', 'desc')
|
||||
->when(auth()->user()->role_id === 5, function ($query) {
|
||||
return $query->where('user_id', auth()->id());
|
||||
})
|
||||
->limit(5)
|
||||
->get();
|
||||
|
||||
$incomeByBarber = User::with('biography')
|
||||
->barbershop()
|
||||
->barber()
|
||||
->withSum(['transactions' => function ($query) {
|
||||
$query->when(auth()->user()->role_id === 5, function ($query) {
|
||||
return $query->where('user_id', auth()->id());
|
||||
});
|
||||
}], 'total')
|
||||
->orderBy('transactions_sum_total', 'desc')
|
||||
->withCount(['transactions' => function ($query) {
|
||||
$query->when(auth()->user()->role_id === 5, function ($query) {
|
||||
return $query->where('user_id', auth()->id());
|
||||
});
|
||||
}]);
|
||||
if (in_array(auth()->user()->role_id, [1, 2, 3])) {
|
||||
$incomeByBarber = $incomeByBarber->get();
|
||||
} elseif (auth()->user()->role_id === 5) {
|
||||
$incomeByBarber = $incomeByBarber->find(auth()->id());
|
||||
$incomeByBarber = (object) [
|
||||
'transactions_sum_total' => formatToRupiah($incomeByBarber->transactions_sum_total),
|
||||
'transactions_count' => $incomeByBarber->transactions_count,
|
||||
];
|
||||
}
|
||||
|
||||
return view('pages.admin.dashboard.analytic', [
|
||||
'pageTitle' => 'Analitik',
|
||||
'totalIncome' => $totalIncome,
|
||||
@ -60,6 +111,7 @@ public function index(): View
|
||||
'topBarber' => $topBarber,
|
||||
'totalUser' => $totalUser,
|
||||
'totalBarber' => $totalBarber,
|
||||
'topCustomersByTotal' => $topCustomersByTotal,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -106,8 +158,20 @@ public function filter(Request $request): JsonResponse
|
||||
$query->whereBetween('created_at', [
|
||||
Carbon::parse($startDate)->startOfDay(),
|
||||
Carbon::parse($endDate)->endOfDay(),
|
||||
]);
|
||||
])
|
||||
->when(auth()->user()->role_id === 5, function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
});
|
||||
}])
|
||||
->when(auth()->user()->role_id === 5, function ($query) {
|
||||
$query->whereHas('transactions', function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
});
|
||||
})
|
||||
->whereBetween('created_at', [
|
||||
Carbon::parse($startDate)->startOfDay(),
|
||||
Carbon::parse($endDate)->endOfDay(),
|
||||
])
|
||||
->get();
|
||||
|
||||
$paymentMethod = Transaction::select('payment_method', DB::raw('SUM(total) as total_amount'))
|
||||
@ -116,6 +180,9 @@ public function filter(Request $request): JsonResponse
|
||||
Carbon::parse($startDate)->startOfDay(),
|
||||
Carbon::parse($endDate)->endOfDay(),
|
||||
])
|
||||
->when(auth()->user()->role_id === 5, function ($query) {
|
||||
return $query->where('user_id', auth()->id());
|
||||
})
|
||||
->groupBy('payment_method')
|
||||
->get();
|
||||
|
||||
@ -177,6 +244,55 @@ public function filter(Request $request): JsonResponse
|
||||
->barber()
|
||||
->count();
|
||||
|
||||
$topCustomersByTotal = Transaction::groupBy('customer_id')
|
||||
->select(
|
||||
'customer_id',
|
||||
DB::raw('SUM(total) as total_transaction'),
|
||||
DB::raw('COUNT(*) as transaction_count')
|
||||
)
|
||||
->whereBetween('created_at', [
|
||||
Carbon::parse($startDate)->startOfDay(),
|
||||
Carbon::parse($endDate)->endOfDay(),
|
||||
])
|
||||
->orderBy('total_transaction', 'desc')
|
||||
->when(auth()->user()->role_id === 5, function ($query) {
|
||||
return $query->where('user_id', auth()->id());
|
||||
})
|
||||
->limit(5)
|
||||
->get();
|
||||
|
||||
$renderCustomerByTotal = view('partials.admin._customer-by-total', compact('topCustomersByTotal'))->render();
|
||||
|
||||
$incomeByBarber = User::with('biography')
|
||||
->barbershop()
|
||||
->barber()
|
||||
->withSum(['transactions' => function ($query) use ($startDate, $endDate) {
|
||||
$query->whereBetween('created_at', [
|
||||
Carbon::parse($startDate)->startOfDay(),
|
||||
Carbon::parse($endDate)->endOfDay(),
|
||||
])->when(auth()->user()->role_id === 5, function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
});
|
||||
}], 'total')
|
||||
->orderBy('transactions_sum_total', 'desc')
|
||||
->withCount(['transactions' => function ($query) use ($startDate, $endDate) {
|
||||
$query->whereBetween('created_at', [
|
||||
Carbon::parse($startDate)->startOfDay(),
|
||||
Carbon::parse($endDate)->endOfDay(),
|
||||
])->when(auth()->user()->role_id === 5, function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
});
|
||||
}]);
|
||||
if (in_array(auth()->user()->role_id, [1, 2, 3])) {
|
||||
$incomeByBarber = $incomeByBarber->get();
|
||||
} elseif (auth()->user()->role_id === 5) {
|
||||
$incomeByBarber = $incomeByBarber->find(auth()->id());
|
||||
$incomeByBarber = [
|
||||
'transactions_sum_total' => formatToRupiah($incomeByBarber->transactions_sum_total ?? 0),
|
||||
'transactions_count' => $incomeByBarber->transactions_count,
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'Data Successfully Retrieved',
|
||||
@ -194,6 +310,7 @@ public function filter(Request $request): JsonResponse
|
||||
'topBarber' => $topBarber,
|
||||
'totalUser' => $totalUser,
|
||||
'totalBarber' => $totalBarber,
|
||||
'renderCustomerByTotal' => $renderCustomerByTotal,
|
||||
],
|
||||
], 200);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ let incomeByBarberCtx = document.getElementById('incomeByBarberChart').getContex
|
||||
|
||||
let incomeByBarberLabels = incomeByBarber.map(incomeByBarber => incomeByBarber.biography.full_name);
|
||||
let incomeByBarberData = incomeByBarber.map(incomeByBarber => incomeByBarber.transactions_sum_total);
|
||||
console.log(incomeByBarberLabels, incomeByBarberData)
|
||||
|
||||
let incomeByBarberBackgroundColors = incomeByBarberData.map(() => getRandomColor());
|
||||
let incomeByBarberBorderColors = incomeByBarberBackgroundColors.map(color => color.replace('0.2', '1'));
|
||||
|
||||
@ -30,15 +30,25 @@ $(document).ready(function () {
|
||||
$("#top-barber-name").text(response.data.topBarber.biography.full_name || "-deleted-");
|
||||
$("#top-barber-total").text(formatToRupiah(response.data.topBarber.transactions_sum_total));
|
||||
|
||||
if (userRole === 5) {
|
||||
$("#top-customers-by-total").empty();
|
||||
$("#top-customers-by-total").html(response.data.renderCustomerByTotal);
|
||||
|
||||
$("#total-transaction").text(response.data.incomeByBarber.transactions_count);
|
||||
$("#total-income").text(response.data.incomeByBarber.transactions_sum_total);
|
||||
}
|
||||
|
||||
// income expense
|
||||
let totalIncome = response.data.totalIncome;
|
||||
let totalExpense = response.data.totalExpense;
|
||||
|
||||
incomeExpenseChart.data.datasets[0].data = [
|
||||
totalIncome,
|
||||
totalExpense,
|
||||
];
|
||||
incomeExpenseChart.update();
|
||||
if (userRole !== 5) {
|
||||
incomeExpenseChart.data.datasets[0].data = [
|
||||
totalIncome,
|
||||
totalExpense,
|
||||
];
|
||||
incomeExpenseChart.update();
|
||||
}
|
||||
|
||||
// top service
|
||||
let topService = response.data.topService;
|
||||
@ -70,22 +80,26 @@ $(document).ready(function () {
|
||||
paymentMethodChart.update();
|
||||
|
||||
// income by barber
|
||||
let updatedIncomeByBarber = response.data.incomeByBarber;
|
||||
let updatedLabels = updatedIncomeByBarber.map(item => item.biography.full_name);
|
||||
let updatedData = updatedIncomeByBarber.map(item => item.transactions_sum_total);
|
||||
if (userRole !== 5) {
|
||||
let updatedIncomeByBarber = response.data.incomeByBarber;
|
||||
let updatedLabels = updatedIncomeByBarber.map(item => item.biography.full_name);
|
||||
let updatedData = updatedIncomeByBarber.map(item => item.transactions_sum_total);
|
||||
|
||||
incomeByBarberChart.data.labels = updatedLabels;
|
||||
incomeByBarberChart.data.datasets[0].data = updatedData;
|
||||
incomeByBarberChart.update();
|
||||
incomeByBarberChart.data.labels = updatedLabels;
|
||||
incomeByBarberChart.data.datasets[0].data = updatedData;
|
||||
incomeByBarberChart.update();
|
||||
}
|
||||
|
||||
// transaction by barber
|
||||
let transactionByBarber = response.data.transactionByBarber;
|
||||
let transactionByBarberLabels = transactionByBarber.map(item => item.biography.full_name);
|
||||
let transactionByBarberData = transactionByBarber.map(item => item.transactions_count);
|
||||
if (userRole !== 5) {
|
||||
let transactionByBarber = response.data.transactionByBarber;
|
||||
let transactionByBarberLabels = transactionByBarber.map(item => item.biography.full_name);
|
||||
let transactionByBarberData = transactionByBarber.map(item => item.transactions_count);
|
||||
|
||||
transactionByBarberChart.data.labels = transactionByBarberLabels;
|
||||
transactionByBarberChart.data.datasets[0].data = transactionByBarberData;
|
||||
transactionByBarberChart.update();
|
||||
transactionByBarberChart.data.labels = transactionByBarberLabels;
|
||||
transactionByBarberChart.data.datasets[0].data = transactionByBarberData;
|
||||
transactionByBarberChart.update();
|
||||
}
|
||||
},
|
||||
error: function (xhr) { },
|
||||
});
|
||||
|
||||
@ -19,101 +19,104 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row widget-grid">
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card small-widget">
|
||||
<div class="card-body primary">
|
||||
<span class="f-light">Total Aset</span>
|
||||
<div class="d-flex align-items-end gap-1">
|
||||
<h4 id="total-asset">{{ formatToRupiah($totalAsset) }}</h4>
|
||||
</div>
|
||||
<div class="bg-gradient">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<ul class="user-list">
|
||||
<li>
|
||||
<div class="user-icon primary">
|
||||
<div class="user-box">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
||||
viewBox="-3 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round"
|
||||
class="feather feather-user-plus font-primary">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="8.5" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="mb-1" id="total-barber">{{ $totalBarber }}</h5>
|
||||
<span class="font-primary d-flex align-items-center">
|
||||
<i class="icon-arrow-up icon-rotate me-1"> </i>
|
||||
<span class="f-w-500">Barber</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="user-icon success">
|
||||
<div class="user-box">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
||||
viewBox="-3 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round"
|
||||
class="feather feather-user-minus font-success">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="8.5" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="mb-1" id="total-user">{{ $totalUser }}</h5>
|
||||
<span class="font-danger d-flex align-items-center">
|
||||
<i class="icon-arrow-down icon-rotate me-1"></i>
|
||||
<span class="f-w-500">Semua</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@if ($topBarber && $topBarber->transactions_sum_total)
|
||||
<div class="card 0-hidden">
|
||||
<div class="card-body balance-widget">
|
||||
<span class="f-w-500 f-light">Top Barber</span>
|
||||
<h4 class="mb-3 mt-1 f-w-500 mb-0 f-22">
|
||||
<span class="counter"
|
||||
id="top-barber-name">{{ $topBarber->biography->full_name ?? '-deleted-' }}</span>
|
||||
</h4>
|
||||
<span class=" btn-hover-effect f-w-500"
|
||||
id="top-barber-total">{{ formatToRupiah($topBarber->transactions_sum_total ?? 0) }}</span>
|
||||
<div class="mobile-right-img">
|
||||
<img class="mobile-img" src="{{ asset('assets/admin/images/crown.png') }}"
|
||||
alt="mobile with coin">
|
||||
@if (auth()->user()->role_id !== 5)
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card small-widget">
|
||||
<div class="card-body primary">
|
||||
<span class="f-light">Total Aset</span>
|
||||
<div class="d-flex align-items-end gap-1">
|
||||
<h4 id="total-asset">{{ formatToRupiah($totalAsset) }}</h4>
|
||||
</div>
|
||||
<div class="bg-gradient">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<h5>Grafik Keuangan</h5>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<ul class="user-list">
|
||||
<li>
|
||||
<div class="user-icon primary">
|
||||
<div class="user-box">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
||||
viewBox="-3 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round"
|
||||
class="feather feather-user-plus font-primary">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="8.5" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="mb-1" id="total-barber">{{ $totalBarber }}</h5>
|
||||
<span class="font-primary d-flex align-items-center">
|
||||
<i class="icon-arrow-up icon-rotate me-1"> </i>
|
||||
<span class="f-w-500">Barber</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="user-icon success">
|
||||
<div class="user-box">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
||||
viewBox="-3 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round"
|
||||
class="feather feather-user-minus font-success">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="8.5" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="mb-1" id="total-user">{{ $totalUser }}</h5>
|
||||
<span class="font-danger d-flex align-items-center">
|
||||
<i class="icon-arrow-down icon-rotate me-1"></i>
|
||||
<span class="f-w-500">Semua</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="row m-0 overall-card">
|
||||
<div class="chart-right">
|
||||
<div class="card-body p-0">
|
||||
<p>Keuntungan : <span
|
||||
id="net-income">{{ formatToRupiah($totalIncome - $totalExpense) }}</span></p>
|
||||
<div class="current-sale-container">
|
||||
<canvas id="incomeExpenseChart" width="400" height="400"></canvas>
|
||||
@if ($topBarber && $topBarber->transactions_sum_total)
|
||||
<div class="card 0-hidden">
|
||||
<div class="card-body balance-widget">
|
||||
<span class="f-w-500 f-light">Top Barber</span>
|
||||
<h4 class="mb-3 mt-1 f-w-500 mb-0 f-22">
|
||||
<span class="counter"
|
||||
id="top-barber-name">{{ $topBarber->biography->full_name ?? '-deleted-' }}</span>
|
||||
</h4>
|
||||
<span class=" btn-hover-effect f-w-500"
|
||||
id="top-barber-total">{{ formatToRupiah($topBarber->transactions_sum_total ?? 0) }}</span>
|
||||
<div class="mobile-right-img">
|
||||
<img class="mobile-img" src="{{ asset('assets/admin/images/crown.png') }}"
|
||||
alt="mobile with coin">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<h5>Grafik Keuangan</h5>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="row m-0 overall-card">
|
||||
<div class="chart-right">
|
||||
<div class="card-body p-0">
|
||||
<p>Keuntungan : <span
|
||||
id="net-income">{{ formatToRupiah($totalIncome - $totalExpense) }}</span>
|
||||
</p>
|
||||
<div class="current-sale-container">
|
||||
<canvas id="incomeExpenseChart" width="400" height="400"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
@ -150,42 +153,107 @@ class="feather feather-user-minus font-success">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<h5>Pendapatan By Barber</h5>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="row m-0 overall-card">
|
||||
<div class="chart-right">
|
||||
<div class="card-body p-0">
|
||||
<div class="current-sale-container">
|
||||
<canvas id="incomeByBarberChart" width="400" height="400"></canvas>
|
||||
@if (auth()->user()->role_id !== 5)
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<h5>Pendapatan By Barber</h5>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="row m-0 overall-card">
|
||||
<div class="chart-right">
|
||||
<div class="card-body p-0">
|
||||
<div class="current-sale-container">
|
||||
<canvas id="incomeByBarberChart" width="400" height="400"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<h5>Transaksi By Barber</h5>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="row m-0 overall-card">
|
||||
<div class="chart-right">
|
||||
<div class="card-body p-0">
|
||||
<div class="current-sale-container">
|
||||
<canvas id="transactionByBarberChart" width="400" height="400"></canvas>
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<h5>Transaksi By Barber</h5>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="row m-0 overall-card">
|
||||
<div class="chart-right">
|
||||
<div class="card-body p-0">
|
||||
<div class="current-sale-container">
|
||||
<canvas id="transactionByBarberChart" width="400" height="400"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<div class="header-top">
|
||||
<h5 class="m-0">Top Pelanggan</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="table-responsive custom-scrollbar">
|
||||
<table class="table table-dashed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nama</th>
|
||||
<th>Kontak</th>
|
||||
<th>Jumlah Transaksi</th>
|
||||
<th>Total Transakski</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="top-customers-by-total">
|
||||
@foreach ($topCustomersByTotal as $item)
|
||||
<tr>
|
||||
<td>{{ $item->customer->name ?? '--deleted--' }}</td>
|
||||
<td>{{ $item->customer->contact_number ?? '-' }}</td>
|
||||
<td>{{ $item->transaction_count }}</td>
|
||||
<td>{{ formatToRupiah($item->total_transaction) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header card-no-border">
|
||||
<div class="header-top">
|
||||
<h5 class="m-0">Pendapatan Barber</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<div class="table-responsive custom-scrollbar">
|
||||
<table class="table table-dashed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Jumlah Transaksi</th>
|
||||
<th>Total Transakski</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td id="total-transaction">{{ $incomeByBarber->transactions_count }}</td>
|
||||
<td id="total-income">
|
||||
{{ $incomeByBarber->transactions_sum_total }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -196,12 +264,16 @@ class="feather feather-user-minus font-success">
|
||||
@section('afterScripts')
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.6/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
let userRole = {!! auth()->user()->role_id !!}
|
||||
|
||||
const totalIncome = @json($totalIncome);
|
||||
const totalExpense = @json($totalExpense);
|
||||
const topService = @json($topService);
|
||||
const paymentMethod = @json($paymentMethod);
|
||||
const incomeByBarber = @json($incomeByBarber);
|
||||
const transactionByBarber = @json($transactionByBarber);
|
||||
const topCustomersByTotal = @json($topCustomersByTotal);
|
||||
const topBarber = @json($topBarber);
|
||||
</script>
|
||||
<script src="{{ asset('assets/admin/js/random-color.js?ver=1.0.0') }}"></script>
|
||||
<script src="{{ asset('assets/admin/js/chart/finance.js?ver=1.0.0') }}"></script>
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
@foreach ($topCustomersByTotal as $item)
|
||||
<tr>
|
||||
<td>{{ $item->customer->name ?? '--deleted--' }}</td>
|
||||
<td>{{ $item->customer->contact_number ?? '-' }}</td>
|
||||
<td>{{ $item->transaction_count }}</td>
|
||||
<td>{{ formatToRupiah($item->total_transaction) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@ -49,7 +49,7 @@
|
||||
<span>Ringkasan</span>
|
||||
</a>
|
||||
</li>
|
||||
@if (in_array(auth()->user()->role_id, [1, 2, 3]))
|
||||
@if (auth()->user()->role_id !== 4)
|
||||
<li class="sidebar-list">
|
||||
<i class="fa fa-thumb-tack"></i>
|
||||
<a class="sidebar-link sidebar-title link-nav" href="{{ route('dashboard.analytic') }}">
|
||||
@ -57,6 +57,8 @@
|
||||
<span>Analitik</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@if (in_array(auth()->user()->role_id, [1, 2, 3]))
|
||||
<li class="sidebar-main-title">
|
||||
<div>
|
||||
<h6>Master</h6>
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
use App\Http\Controllers\Client\HomepageController;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Psy\Readline\Transient;
|
||||
|
||||
Route::prefix('auth')->group(function () {
|
||||
Route::get('login', [LoginController::class, 'index'])->name('login');
|
||||
@ -32,8 +31,8 @@
|
||||
'prefix' => 'dashboard',
|
||||
], function () {
|
||||
Route::get('overview', [OverviewController::class, 'index'])->name('dashboard.overview');
|
||||
Route::get('analytic', [AnalyticController::class, 'index'])->name('dashboard.analytic')->middleware('check_role:1,2,3');
|
||||
Route::get('analytic/filter', [AnalyticController::class, 'filter'])->name('dashboard.analytic.filter')->middleware('check_role:1,2,3');
|
||||
Route::get('analytic', [AnalyticController::class, 'index'])->name('dashboard.analytic')->middleware('check_role:1,2,3,5');
|
||||
Route::get('analytic/filter', [AnalyticController::class, 'filter'])->name('dashboard.analytic.filter')->middleware('check_role:1,2,3,5');
|
||||
|
||||
Route::get('change-barbershop/{barbershop}', [OverviewController::class, 'changeBarbershop'])->name('dashboard.changeBarbershop');
|
||||
|
||||
@ -181,6 +180,6 @@
|
||||
|
||||
Route::get('/print-page', function () {
|
||||
return view('print-page', [
|
||||
'transaction' => Transaction::first()
|
||||
'transaction' => Transaction::first(),
|
||||
]); // Ganti dengan nama view halaman cetak Anda
|
||||
})->name('print.page');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user