feat(overview): custom halaman ringkasan,menambahkan scope model Customer,Expense dan Transaction,menambahkan image dan custom css

This commit is contained in:
Yoga Pangestu 2024-11-27 18:36:47 +07:00
parent 5c5e402552
commit 5f8b09f9d1
8 changed files with 226 additions and 41 deletions

View File

@ -3,13 +3,63 @@
namespace App\Http\Controllers\Admin\Dashboard;
use App\Http\Controllers\Controller;
use App\Models\Barbershop;
use App\Models\Expense;
use App\Models\Transaction;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class OverviewController extends Controller
{
public function index()
{
$todayIncome = Transaction::query()->barbershop()->whereDate('created_at', now()->today())->sum('total');
$yesterdayIncome = Transaction::query()->barbershop()->whereDate('created_at', now()->yesterday())->sum('total');
$todayShaving = Transaction::query()->barbershop()->today()->count();
$yesterdayShaving = Transaction::query()->barbershop()->yesterday()->count();
$todayExpense = Expense::query()->barbershop()->today()->sum('amount');
$yesterdayExpense = Expense::query()->barbershop()->yesterday()->sum('amount');
$todayNewCustomer = Transaction::with('customer')->whereDoesntHave('customer.transactions', function ($query) {
$query->where('id', '<>', DB::raw('transactions.id'));
})
->barbershop()
->today()
->distinct('customer_id')
->count('customer_id');
$yesterdayNewCustomer = Transaction::with('customer')->whereDoesntHave('customer.transactions', function ($query) {
$query->where('id', '<>', DB::raw('transactions.id'));
})
->barbershop()
->yesterday()
->distinct('customer_id')
->count('customer_id');
$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')
->limit(5)
->get();
return view('pages.admin.dashboard.overview', [
'pageTitle' => 'Ringkasan',
'todayIncome' => $todayIncome,
'diffIncome' => $todayIncome - $yesterdayIncome,
'todayShaving' => $todayShaving,
'diffShaving' => $todayShaving - $yesterdayShaving,
'todayExpense' => $todayExpense,
'diffExpense' => $todayExpense - $yesterdayExpense,
'todayNewCustomer' => $todayNewCustomer,
'diffNewCustomer' => $todayNewCustomer - $yesterdayNewCustomer,
'cash' => Barbershop::findOrFail(Auth::user()->barbershop_id)->cash,
'topCustomersByTotal' => $topCustomersByTotal,
]);
}
}

View File

@ -2,10 +2,13 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
class Customer extends Model
{
@ -18,6 +21,11 @@ class Customer extends Model
'contact_number',
];
public function scopeBarbershop(Builder $query): Builder
{
return $query->where('barbershop_id', Auth::user()->barbershop_id);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
@ -27,4 +35,9 @@ public function barbershop(): BelongsTo
{
return $this->belongsTo(Barbershop::class);
}
public function transactions(): HasMany
{
return $this->hasMany(Transaction::class);
}
}

View File

@ -3,12 +3,15 @@
namespace App\Models;
use App\Observers\ExpenseObserver;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
#[ObservedBy([ExpenseObserver::class])]
class Expense extends Model
@ -23,6 +26,21 @@ class Expense extends Model
'use_cash',
];
public function scopeBarbershop(Builder $query): Builder
{
return $query->where('barbershop_id', Auth::user()->barbershop_id);
}
public function scopeToday(Builder $query): Builder
{
return $query->whereDate('created_at', Carbon::today());
}
public function scopeYesterday(Builder $query): Builder
{
return $query->whereDate('created_at', Carbon::yesterday());
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);

View File

@ -2,11 +2,14 @@
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
class Transaction extends Model
{
@ -23,6 +26,21 @@ class Transaction extends Model
'payment_method',
];
public function scopeBarbershop(Builder $query): Builder
{
return $query->where('barbershop_id', Auth::user()->barbershop_id);
}
public function scopeToday(Builder $query): Builder
{
return $query->whereDate('created_at', Carbon::today());
}
public function scopeYesterday(Builder $query): Builder
{
return $query->whereDate('created_at', Carbon::yesterday());
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);

View File

@ -18644,7 +18644,7 @@ .widget-decor {
}
.balance-widget {
background-image: url(../images/dashboard-2/balance-bg.png);
background-image: url(../images/balance-bg.png);
background-size: cover;
background-repeat: no-repeat;
background-position: right;

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -2,49 +2,136 @@
@section('styles')
@endsection
@section('app')
<div class="container-fluid" onload="startTime()">
<div class="row widget-grid">
<div class="col-xxl-4 col-sm-6 box-col-6">
<div class="card profile-box">
<div class="card-body">
<div class="media media-wrapper justify-content-between">
<div class="media-body">
<div class="greeting-user">
<h4 class="f-w-600">Selamat Datang</h4>
<p style="max-width: 70%">Inilah yang terjadi di akun Anda hari ini</p>
<div class="whatsnew-btn"></div>
<div class="container-fluid">
<div class="row size-column">
<div class="col-xxl-10 col-md-12 box-col-8 grid-ed-12">
<div class="row">
<div class="col-xxl-5 col-md-7 box-col-7">
<div class="row">
<div class="col-sm-12">
<div class="card o-hidden">
<div class="card-body balance-widget">
<span class="f-w-500 f-light">Kas</span>
<h4 class="mb-3 mt-1 f-w-500 mb-0 f-22">
<span class="counter">{{ formatToRupiah($cash) }}</span>
</h4>
<a class="purchase-btn btn btn-primary btn-hover-effect f-w-500"
href="{{ route('finance.cashes') }}">Tambah Kas</a>
<div class="mobile-right-img">
<img class="mobile-img" src="{{ asset('assets/admin/images/mobile.png') }}"
alt="mobile with coin">
</div>
</div>
</div>
</div>
<div>
<div class="clockbox">
<svg id="clock" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<g id="face">
<circle class="circle" cx="300" cy="300" r="253.9"></circle>
<path class="hour-marks"
d="M300.5 94V61M506 300.5h32M300.5 506v33M94 300.5H60M411.3 107.8l7.9-13.8M493 190.2l13-7.4M492.1 411.4l16.5 9.5M411 492.3l8.9 15.3M189 492.3l-9.2 15.9M107.7 411L93 419.5M107.5 189.3l-17.1-9.9M188.1 108.2l-9-15.6">
</path>
<circle class="mid-circle" cx="300" cy="300" r="16.2"></circle>
</g>
<g id="hour">
<path class="hour-hand" d="M300.5 298V142"></path>
<circle class="sizing-box" cx="300" cy="300" r="253.9"></circle>
</g>
<g id="minute">
<path class="minute-hand" d="M300.5 298V67"> </path>
<circle class="sizing-box" cx="300" cy="300" r="253.9"></circle>
</g>
<g id="second">
<path class="second-hand" d="M300.5 350V55"></path>
<circle class="sizing-box" cx="300" cy="300" r="253.9"> </circle>
</g>
</svg>
<div class="col-6">
<div class="card small-widget">
<div class="card-body primary">
<span class="f-light">Pendapatan</span>
<div class="d-flex align-items-end gap-1">
<h4>{{ formatToRupiah($todayIncome) }}</h4>
<span class="font-primary f-12 f-w-500">
<i class="icon-arrow-up"></i>
<span>
{{ formatToRupiah($diffIncome) > 0 ? '+' : '' }}{{ formatToRupiah($diffIncome) }}</span>
</span>
</div>
<div class="bg-gradient">
</div>
</div>
</div>
</div>
<div class="col-6">
<div class="card small-widget">
<div class="card-body secondary">
<span class="f-light">Cukur</span>
<div class="d-flex align-items-end gap-1">
<h4>{{ $todayShaving }}</h4>
<span class="font-secondary f-12 f-w-500">
<i class="icon-arrow-up"></i>
<span> {{ $diffShaving > 0 ? '+' : '' }}{{ $diffShaving }}</span>
</span>
</div>
<div class="bg-gradient">
<svg class="stroke-icon svg-fill">
</svg>
</div>
</div>
</div>
</div>
<div class="col-6">
<div class="card small-widget">
<div class="card-body secondary">
<span class="f-light">Pengeluaran</span>
<div class="d-flex align-items-end gap-1">
<h4>{{ formatToRupiah($todayExpense) }}</h4>
<span class="font-secondary f-12 f-w-500">
<i class="icon-arrow-up"></i>
<span>
{{ formatToRupiah($diffExpense) > 0 ? '+' : '' }}{{ formatToRupiah($diffExpense) }}</span>
</span>
</div>
<div class="bg-gradient">
<svg class="stroke-icon svg-fill">
</svg>
</div>
</div>
</div>
</div>
<div class="col-6">
<div class="card small-widget">
<div class="card-body success">
<span class="f-light">Pelanggan Baru</span>
<div class="d-flex align-items-end gap-1">
<h4>{{ $todayNewCustomer }}</h4>
<span class="font-success f-12 f-w-500">
<i class="icon-arrow-up"></i>
<span>
{{ $diffNewCustomer > 0 ? '+' : '' }}{{ $diffNewCustomer }}</span>
</span>
</div>
<div class="bg-gradient">
<svg class="stroke-icon svg-fill">
</svg>
</div>
</div>
</div>
<div class="badge f-10 p-0" id="txt"></div>
</div>
</div>
<div class="cartoon">
<img class="img-fluid" src="{{ asset('assets/admin/images/barber.png') }}" style="width: 60%"
alt="barber">
</div>
<div class="col-xxl-7 col-md-5 col-sm-6 box-col-5">
<div class="appointment">
<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>
@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>
</div>
@ -52,6 +139,5 @@
</div>
</div>
@endsection
@section('beforeScripts')
<script src="{{ asset('assets/admin/js/clock.js?ver=1.0.0') }}"></script>
@section('afterScript')
@endsection