refactor: Optimize analysis page by restructuring form components, enhancing date filter functionality, and improving customer and order statistics display.

This commit is contained in:
Yoga Pangestu 2026-03-09 19:06:34 +07:00
parent b424d119fc
commit e11accb8cc
4 changed files with 142 additions and 130 deletions

View File

@ -18,10 +18,10 @@
use Filament\Forms\Concerns\InteractsWithForms; use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms; use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page; use Filament\Pages\Page;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon; use Filament\Support\Icons\Heroicon;
use Illuminate\Support\Facades\DB;
class Analisys extends Page implements HasForms class Analisys extends Page implements HasForms
{ {
@ -44,57 +44,56 @@ public function form(Schema $form): Schema
->schema([ ->schema([
Section::make() Section::make()
->schema([ ->schema([
Grid::make(3) Select::make('period')
->schema([ ->label('Periode Cepat')
Select::make('period') ->options([
->label('Periode Cepat') 'today' => 'Hari Ini',
->options([ 'this_week' => 'Minggu Ini',
'today' => 'Hari Ini', 'this_month' => 'Bulan Ini',
'this_week' => 'Minggu Ini', 'this_year' => 'Tahun Ini',
'this_month' => 'Bulan Ini', 'custom' => 'Kustom Tanggal',
'this_year' => 'Tahun Ini', ])
'custom' => 'Kustom Tanggal', ->live()
]) ->afterStateUpdated(function ($state, $set, $get) {
->live() if ($state === 'today') {
->afterStateUpdated(function ($state, $set, $get) { $set('from_date', now()->format('d F Y'));
if ($state === 'today') { $set('to_date', now()->format('d F Y'));
$set('from_date', now()->format('d F Y')); } elseif ($state === 'this_week') {
$set('to_date', now()->format('d F Y')); $set('from_date', now()->startOfWeek()->format('d F Y'));
} elseif ($state === 'this_week') { $set('to_date', now()->endOfWeek()->format('d F Y'));
$set('from_date', now()->startOfWeek()->format('d F Y')); } elseif ($state === 'this_month') {
$set('to_date', now()->endOfWeek()->format('d F Y')); $set('from_date', now()->startOfMonth()->format('d F Y'));
} elseif ($state === 'this_month') { $set('to_date', now()->endOfMonth()->format('d F Y'));
$set('from_date', now()->startOfMonth()->format('d F Y')); } elseif ($state === 'this_year') {
$set('to_date', now()->endOfMonth()->format('d F Y')); $set('from_date', now()->startOfYear()->format('d F Y'));
} elseif ($state === 'this_year') { $set('to_date', now()->endOfYear()->format('d F Y'));
$set('from_date', now()->startOfYear()->format('d F Y')); }
$set('to_date', now()->endOfYear()->format('d F Y')); $this->dispatch('stats-updated');
} })
$this->dispatch('stats-updated'); ->native(false),
}),
DatePicker::make('from_date') DatePicker::make('from_date')
->label('Dari Tanggal') ->label('Dari Tanggal')
->native(false) ->native(false)
->displayFormat('d F Y') ->displayFormat('d F Y')
->live() ->live()
->afterStateUpdated(function ($set) { ->afterStateUpdated(function ($set) {
$set('period', 'custom'); $set('period', 'custom');
$this->dispatch('stats-updated'); $this->dispatch('stats-updated');
}), }),
DatePicker::make('to_date') DatePicker::make('to_date')
->label('Sampai Tanggal') ->label('Sampai Tanggal')
->native(false) ->native(false)
->displayFormat('d F Y') ->displayFormat('d F Y')
->live() ->live()
->afterStateUpdated(function ($set) { ->afterStateUpdated(function ($set) {
$set('period', 'custom'); $set('period', 'custom');
$this->dispatch('stats-updated'); $this->dispatch('stats-updated');
}), }),
]),
]) ])
->compact(), ->compact()
->columns(3),
]) ])
->statePath('data'); ->statePath('data');
} }
@ -121,10 +120,10 @@ public function getViewData(): array
$fromDate = Carbon::parse($fromDateInput)->format('Y-m-d'); $fromDate = Carbon::parse($fromDateInput)->format('Y-m-d');
$toDate = Carbon::parse($toDateInput)->format('Y-m-d'); $toDate = Carbon::parse($toDateInput)->format('Y-m-d');
// 1. Count customers // 1. Customer Count
$countPelanggan = Customer::count(); $customerCount = Customer::count();
// 2. Count total eggs (by unit) // 2. Egg Production by Unit - Optimized join query
$totalEggsByUnit = EggCollectionItem::query() $totalEggsByUnit = EggCollectionItem::query()
->join('egg_collections', 'egg_collection_items.egg_collection_id', '=', 'egg_collections.id') ->join('egg_collections', 'egg_collection_items.egg_collection_id', '=', 'egg_collections.id')
->join('units', 'egg_collection_items.unit_id', '=', 'units.id') ->join('units', 'egg_collection_items.unit_id', '=', 'units.id')
@ -141,11 +140,15 @@ public function getViewData(): array
'total_broken' => $formatNumber($item->total_broken), 'total_broken' => $formatNumber($item->total_broken),
]); ]);
// 3. Count total orders // 3. Orders Stats - Combined count and sum
$countPesanan = Order::whereBetween('order_date', [$fromDate, $toDate])->count(); $orderStats = Order::whereBetween('order_date', [$fromDate, $toDate])
->selectRaw('count(*) as count, sum(total_amount) as total')
->first();
$orderCount = (int) ($orderStats->count ?? 0);
$orderRevenue = (float) ($orderStats->total ?? 0);
// 4. Count total delayed goods (by unit) // 4. Delayed Goods Stats - Combined by unit
$totalDelayedByUnit = DelayedGood::query() $delayedStatsByUnit = DelayedGood::query()
->join('units', 'delayed_goods.unit_id', '=', 'units.id') ->join('units', 'delayed_goods.unit_id', '=', 'units.id')
->whereBetween('delayed_goods.stored_date', [$fromDate, $toDate]) ->whereBetween('delayed_goods.stored_date', [$fromDate, $toDate])
->selectRaw('units.name as unit_name, sum(quantity) as total') ->selectRaw('units.name as unit_name, sum(quantity) as total')
@ -156,37 +159,38 @@ public function getViewData(): array
'total' => $formatNumber($item->total), 'total' => $formatNumber($item->total),
]); ]);
// 5. Revenue // 5. Financial Totals in Range
$pendapatanPesanan = Order::whereBetween('order_date', [$fromDate, $toDate])->sum('total_amount'); $delayedTotals = DelayedGood::whereBetween('stored_date', [$fromDate, $toDate])
$pendapatanTertunda = DelayedGood::whereBetween('stored_date', [$fromDate, $toDate])->sum('total_amount'); ->selectRaw('sum(total_amount) as total, sum(paid_amount) as paid')
$totalPendapatan = $pendapatanPesanan + $pendapatanTertunda; ->first();
// 6. Financial totals $delayedRevenue = (float) ($delayedTotals->total ?? 0);
$totalPengeluaran = Expense::whereBetween('expense_date', [$fromDate, $toDate])->sum('amount'); $paidAmountInRange = (float) ($delayedTotals->paid ?? 0);
$totalPenggajian = Payroll::whereBetween('period_month', [Carbon::parse($fromDate)->format('Y-m'), Carbon::parse($toDate)->format('Y-m')])->sum('total_salary'); $totalRevenue = $orderRevenue + $delayedRevenue;
$totalBelanjaPakan = FeedPurchase::whereBetween('purchase_date', [$fromDate, $toDate])->sum('total_price');
$labaKotor = $totalPendapatan - $totalBelanjaPakan; $totalExpenses = (float) Expense::whereBetween('expense_date', [$fromDate, $toDate])->sum('amount');
$labaBersih = $labaKotor - $totalPengeluaran - $totalPenggajian; $totalPayroll = (float) Payroll::whereBetween('period_month', [Carbon::parse($fromDate)->format('Y-m'), Carbon::parse($toDate)->format('Y-m')])->sum('total_salary');
$totalFeedPurchase = (float) FeedPurchase::whereBetween('purchase_date', [$fromDate, $toDate])->sum('total_price');
$paidInRange = DelayedGood::whereBetween('stored_date', [$fromDate, $toDate])->sum('paid_amount'); $grossProfit = $totalRevenue - $totalFeedPurchase;
$totalInRange = DelayedGood::whereBetween('stored_date', [$fromDate, $toDate])->sum('total_amount'); $netProfit = $grossProfit - $totalExpenses - $totalPayroll;
$totalPiutang = $totalInRange - $paidInRange; $totalReceivables = $delayedRevenue - $paidAmountInRange;
$mainStats = [ $mainStats = [
['label' => 'Total Pelanggan', 'desc' => 'Jumlah pelanggan terdaftar', 'value' => $countPelanggan, 'prefix' => ''], ['label' => 'Total Pelanggan', 'desc' => 'Jumlah pelanggan terdaftar', 'value' => $customerCount, 'prefix' => ''],
['label' => 'Total Pesanan', 'desc' => 'Jumlah transaksi pesanan', 'value' => $countPesanan, 'prefix' => ''], ['label' => 'Total Pesanan', 'desc' => 'Jumlah transaksi pesanan', 'value' => $orderCount, 'prefix' => ''],
['label' => 'Laba Bersih', 'desc' => 'Setelah dikurangi beban operasional', 'value' => $formatNumber($labaBersih), 'prefix' => 'Rp'], ['label' => 'Laba Bersih', 'desc' => 'Setelah dikurangi beban operasional', 'value' => $formatNumber($netProfit), 'prefix' => 'Rp'],
['label' => 'Total Piutang', 'desc' => 'Piutang barang tertunda (periode)', 'value' => $formatNumber($totalPiutang), 'prefix' => 'Rp'], ['label' => 'Total Piutang', 'desc' => 'Piutang barang tertunda (periode)', 'value' => $formatNumber($totalReceivables), 'prefix' => 'Rp'],
['label' => 'Total Pendapatan', 'desc' => 'Akumulasi semua pemasukan', 'value' => $formatNumber($totalPendapatan), 'prefix' => 'Rp'], ['label' => 'Total Pendapatan', 'desc' => 'Akumulasi semua pemasukan', 'value' => $formatNumber($totalRevenue), 'prefix' => 'Rp'],
['label' => 'Laba Kotor', 'desc' => 'Pendapatan dikurangi biaya pakan', 'value' => $formatNumber($labaKotor), 'prefix' => 'Rp'], ['label' => 'Laba Kotor', 'desc' => 'Pendapatan dikurangi biaya pakan', 'value' => $formatNumber($grossProfit), 'prefix' => 'Rp'],
['label' => 'Total Pengeluaran', 'desc' => 'Biaya operasional & umum', 'value' => $formatNumber($totalPengeluaran), 'prefix' => 'Rp'], ['label' => 'Total Pengeluaran', 'desc' => 'Biaya operasional & umum', 'value' => $formatNumber($totalExpenses), 'prefix' => 'Rp'],
['label' => 'Total Penggajian', 'desc' => 'Total gaji karyawan', 'value' => $formatNumber($totalPenggajian), 'prefix' => 'Rp'], ['label' => 'Total Penggajian', 'desc' => 'Total gaji karyawan', 'value' => $formatNumber($totalPayroll), 'prefix' => 'Rp'],
['label' => 'Belanja Pakan', 'desc' => 'Total pembelian pakan ayam', 'value' => $formatNumber($totalBelanjaPakan), 'prefix' => 'Rp'], ['label' => 'Belanja Pakan', 'desc' => 'Total pembelian pakan ayam', 'value' => $formatNumber($totalFeedPurchase), 'prefix' => 'Rp'],
]; ];
// Top 5 Customers by Order Amount in Range // 6. Top 5 Customers - Optimized summing
$topCustomers = Customer::query() $topCustomers = Customer::query()
->select('id', 'name', 'phone_number')
->withSum(['orders' => fn ($q) => $q->whereBetween('order_date', [$fromDate, $toDate])], 'total_amount') ->withSum(['orders' => fn ($q) => $q->whereBetween('order_date', [$fromDate, $toDate])], 'total_amount')
->withSum(['delayedGoods' => fn ($q) => $q->whereBetween('stored_date', [$fromDate, $toDate])], 'total_amount') ->withSum(['delayedGoods' => fn ($q) => $q->whereBetween('stored_date', [$fromDate, $toDate])], 'total_amount')
->get() ->get()
@ -199,89 +203,98 @@ public function getViewData(): array
->take(5) ->take(5)
->values(); ->values();
// 7. Chart: Daily Production (In range) // 7. Chart: Daily Production (Optimized query)
$diffDays = Carbon::parse($fromDate)->diffInDays(Carbon::parse($toDate)); $diffDays = Carbon::parse($fromDate)->diffInDays(Carbon::parse($toDate));
$rangeQueryDays = collect(range(0, min($diffDays, 30)))->map(fn ($i) => Carbon::parse($fromDate)->addDays($i)->format('Y-m-d'))->values(); $rangeQueryDays = collect(range(0, min($diffDays, 30)))->map(fn ($i) => Carbon::parse($fromDate)->addDays($i)->format('Y-m-d'))->values();
$productionChart = [ $productionDataMap = EggCollection::whereBetween('production_date', [$fromDate, $toDate])
->selectRaw('production_date, sum(total_eggs) as good, sum(total_broken_eggs) as broken')
->groupBy('production_date')
->get()
->keyBy('production_date');
$productionChartData = [
'labels' => $rangeQueryDays->map(fn ($d) => Carbon::parse($d)->format('d M'))->values(), 'labels' => $rangeQueryDays->map(fn ($d) => Carbon::parse($d)->format('d M'))->values(),
'good' => $rangeQueryDays->map(fn ($d) => (float) EggCollection::whereDate('production_date', $d)->sum('total_eggs'))->values(), 'good' => $rangeQueryDays->map(fn ($d) => (float) ($productionDataMap[$d]->good ?? 0))->values(),
'broken' => $rangeQueryDays->map(fn ($d) => (float) EggCollection::whereDate('production_date', $d)->sum('total_broken_eggs'))->values(), 'broken' => $rangeQueryDays->map(fn ($d) => (float) ($productionDataMap[$d]->broken ?? 0))->values(),
]; ];
// 8. Financial Trends (Monthly - 6 months prior to to_date) // 8. Monthly Financial Trends (Optimized aggregates)
$months = collect(range(0, 5))->map(fn ($i) => Carbon::parse($toDate)->subMonths($i)->format('Y-m'))->reverse(); $months = collect(range(0, 5))->map(fn ($i) => Carbon::parse($toDate)->subMonths($i)->format('Y-m'))->reverse();
$financialChart = [
$monthlyOrderRev = Order::whereIn(DB::raw("DATE_FORMAT(order_date, '%Y-%m')"), $months)
->selectRaw("DATE_FORMAT(order_date, '%Y-%m') as month, sum(total_amount) as total")
->groupBy('month')->pluck('total', 'month');
$monthlyDelayedRev = DelayedGood::whereIn(DB::raw("DATE_FORMAT(stored_date, '%Y-%m')"), $months)
->selectRaw("DATE_FORMAT(stored_date, '%Y-%m') as month, sum(total_amount) as total")
->groupBy('month')->pluck('total', 'month');
$monthlyExpenses = Expense::whereIn(DB::raw("DATE_FORMAT(expense_date, '%Y-%m')"), $months)
->selectRaw("DATE_FORMAT(expense_date, '%Y-%m') as month, sum(amount) as total")
->groupBy('month')->pluck('total', 'month');
$monthlyPayroll = Payroll::whereIn('period_month', $months)
->selectRaw('period_month as month, sum(total_salary) as total')
->groupBy('month')->pluck('total', 'month');
$monthlyFeed = FeedPurchase::whereIn(DB::raw("DATE_FORMAT(purchase_date, '%Y-%m')"), $months)
->selectRaw("DATE_FORMAT(purchase_date, '%Y-%m') as month, sum(total_price) as total")
->groupBy('month')->pluck('total', 'month');
$financialChartData = [
'labels' => $months->map(fn ($m) => Carbon::parse($m)->translatedFormat('M Y'))->values(), 'labels' => $months->map(fn ($m) => Carbon::parse($m)->translatedFormat('M Y'))->values(),
'revenue' => $months->map(function ($m) { 'revenue' => $months->map(fn ($m) => (float) (($monthlyOrderRev[$m] ?? 0) + ($monthlyDelayedRev[$m] ?? 0)))->values(),
$orderRev = Order::whereDate('order_date', 'like', "$m%")->sum('total_amount'); 'expenses' => $months->map(fn ($m) => (float) (($monthlyExpenses[$m] ?? 0) + ($monthlyPayroll[$m] ?? 0) + ($monthlyFeed[$m] ?? 0)))->values(),
$delayedRev = DelayedGood::whereDate('stored_date', 'like', "$m%")->sum('total_amount');
return (float) ($orderRev + $delayedRev);
})->values(),
'expenses' => $months->map(function ($m) {
$exp = Expense::whereDate('expense_date', 'like', "$m%")->sum('amount');
$payroll = Payroll::where('period_month', 'like', "$m%")->sum('total_salary');
$feed = FeedPurchase::whereDate('purchase_date', 'like', "$m%")->sum('total_price');
return (float) ($exp + $payroll + $feed);
})->values(),
]; ];
$financialChartData['profit'] = $financialChartData['revenue']->map(fn ($rev, $i) => (float) ($rev - $financialChartData['expenses'][$i]))->values();
// 8b. Chart: Monthly Profit Trend // 9. Distribution Charts
$financialChart['profit'] = collect($financialChart['revenue'])->map(fn ($rev, $i) => (float) ($rev - $financialChart['expenses'][$i]))->values(); $expenseDistributionData = [
// 9. Chart: Expense Distribution
$expenseDistribution = [
'labels' => ['Gaji Karyawan', 'Belanja Pakan', 'Pengeluaran Umum'], 'labels' => ['Gaji Karyawan', 'Belanja Pakan', 'Pengeluaran Umum'],
'data' => [(float) $totalPenggajian, (float) $totalBelanjaPakan, (float) $totalPengeluaran], 'data' => [(float) $totalPayroll, (float) $totalFeedPurchase, (float) $totalExpenses],
]; ];
// 10. Chart: Sales Distribution by Unit
$salesByUnit = Order::whereBetween('order_date', [$fromDate, $toDate]) $salesByUnit = Order::whereBetween('order_date', [$fromDate, $toDate])
->join('units', 'orders.unit_id', '=', 'units.id') ->join('units', 'orders.unit_id', '=', 'units.id')
->selectRaw('units.name, sum(total_amount) as total') ->selectRaw('units.name, sum(total_amount) as total')
->groupBy('units.name') ->groupBy('units.name')
->get(); ->get();
// 11. Chart: Debt Status (In range) $debtStatusData = [
$debtStatus = [ 'paid' => (float) $paidAmountInRange,
'paid' => (float) $paidInRange, 'unpaid' => (float) ($delayedRevenue - $paidAmountInRange),
'unpaid' => (float) ($totalInRange - $paidInRange),
]; ];
// 12. Chart: Feed Stocks (Current)
$feedStocks = Feed::query() $feedStocks = Feed::query()
->join('units', 'feeds.unit_id', '=', 'units.id') ->join('units', 'feeds.unit_id', '=', 'units.id')
->select('feeds.name', 'feeds.stock', 'units.alias as unit_alias') ->select('feeds.name', 'feeds.stock', 'units.alias as unit_alias')
->get(); ->get();
// 13. Chart: Production by Warehouse (In range)
$productionByWarehouse = EggCollection::whereBetween('production_date', [$fromDate, $toDate]) $productionByWarehouse = EggCollection::whereBetween('production_date', [$fromDate, $toDate])
->join('warehouses', 'egg_collections.warehouse_id', '=', 'warehouses.id') ->join('warehouses', 'egg_collections.warehouse_id', '=', 'warehouses.id')
->selectRaw('warehouses.name, sum(total_eggs) as total') ->selectRaw('warehouses.name, sum(total_eggs) as total')
->groupBy('warehouses.name') ->groupBy('warehouses.name')
->get(); ->get();
// 14. Chart: Revenue Split (In range) $revenueSplitData = [
$revenueSplit = [ 'orders' => (float) $orderRevenue,
'orders' => (float) $pendapatanPesanan, 'delayed' => (float) $delayedRevenue,
'delayed' => (float) $pendapatanTertunda,
]; ];
return [ return [
'mainStats' => $mainStats, 'mainStats' => $mainStats,
'totalEggsByUnit' => $totalEggsByUnit, 'totalEggsByUnit' => $totalEggsByUnit,
'totalDelayedByUnit' => $totalDelayedByUnit, 'totalDelayedByUnit' => $delayedStatsByUnit,
'topCustomers' => $topCustomers, 'topCustomers' => $topCustomers,
'productionChart' => $productionChart, 'productionChart' => $productionChartData,
'financialChart' => $financialChart, 'financialChart' => $financialChartData,
'expenseDistribution' => $expenseDistribution, 'expenseDistribution' => $expenseDistributionData,
'salesByUnit' => [ 'salesByUnit' => [
'labels' => $salesByUnit->pluck('name')->values(), 'labels' => $salesByUnit->pluck('name')->values(),
'data' => $salesByUnit->pluck('total')->map(fn ($v) => (float) $v)->values(), 'data' => $salesByUnit->pluck('total')->map(fn ($v) => (float) $v)->values(),
], ],
'debtStatus' => $debtStatus, 'debtStatus' => $debtStatusData,
'feedStocks' => [ 'feedStocks' => [
'labels' => $feedStocks->pluck('name')->values(), 'labels' => $feedStocks->pluck('name')->values(),
'data' => $feedStocks->pluck('stock')->map(fn ($v) => (float) $v)->values(), 'data' => $feedStocks->pluck('stock')->map(fn ($v) => (float) $v)->values(),
@ -293,7 +306,7 @@ public function getViewData(): array
], ],
'revenueSplit' => [ 'revenueSplit' => [
'labels' => ['Penjualan Langsung', 'Barang Tertunda'], 'labels' => ['Penjualan Langsung', 'Barang Tertunda'],
'data' => [$revenueSplit['orders'], $revenueSplit['delayed']], 'data' => [$revenueSplitData['orders'], $revenueSplitData['delayed']],
], ],
'formatNumber' => $formatNumber, 'formatNumber' => $formatNumber,
]; ];

View File

@ -5,6 +5,7 @@
use AchyutN\FilamentLogViewer\FilamentLogViewer; use AchyutN\FilamentLogViewer\FilamentLogViewer;
use App\Enums\RoleEnum; use App\Enums\RoleEnum;
use App\Filament\Pages\Auth\Login; use App\Filament\Pages\Auth\Login;
use App\Filament\Pages\Dashboard;
use App\Filament\Pages\Profile; use App\Filament\Pages\Profile;
use BezhanSalleh\FilamentShield\FilamentShieldPlugin; use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
use DiogoGPinto\AuthUIEnhancer\AuthUIEnhancerPlugin; use DiogoGPinto\AuthUIEnhancer\AuthUIEnhancerPlugin;
@ -12,7 +13,6 @@
use Filament\Http\Middleware\AuthenticateSession; use Filament\Http\Middleware\AuthenticateSession;
use Filament\Http\Middleware\DisableBladeIconComponents; use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent; use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages\Dashboard;
use Filament\Panel; use Filament\Panel;
use Filament\PanelProvider; use Filament\PanelProvider;
use Filament\Support\Colors\Color; use Filament\Support\Colors\Color;

View File

@ -1,9 +1,8 @@
<x-filament-panels::page> <x-filament-panels::page>
<div class="mb-6"> <form wire:submit="getViewData">
<form wire:submit="getViewData"> {{ $this->form }}
{{ $this->form }} </form>
</form>
</div>
<div class="space-y-6 pb-12"> <div class="space-y-6 pb-12">
{{-- Main Stats Grid --}} {{-- Main Stats Grid --}}
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
@ -21,7 +20,7 @@ class="text-xs font-semibold text-gray-400 dark:text-gray-500">{{ $stat['prefix'
<span class="text-2xl font-bold text-gray-900 dark:text-white">{{ $stat['value'] }}</span> <span class="text-2xl font-bold text-gray-900 dark:text-white">{{ $stat['value'] }}</span>
</div> </div>
<span <span
class="text-[10px] text-gray-400 dark:text-gray-600 italic tracking-wide uppercase">{{ $stat['desc'] }}</span> class="text-[10px] text-gray-900 dark:text-gray-600 italic tracking-wide uppercase">{{ $stat['desc'] }}</span>
</div> </div>
</div> </div>
@endforeach @endforeach
@ -79,7 +78,7 @@ class="px-5 py-4 flex items-center justify-between hover:bg-gray-50 dark:hover:b
<span <span
class="text-sm font-bold text-gray-800 dark:text-gray-200">{{ $customer->name }}</span> class="text-sm font-bold text-gray-800 dark:text-gray-200">{{ $customer->name }}</span>
<span <span
class="text-xs text-gray-400 tracking-tight">{{ $customer->phone ?? 'Telp tidak ada' }}</span> class="text-xs text-gray-400 tracking-tight">{{ $customer->phone_number ?? 'Telp tidak ada' }}</span>
</div> </div>
<div class="text-right"> <div class="text-right">
<span <span

View File

@ -130,7 +130,7 @@ class="px-5 py-4 flex items-center justify-between hover:bg-gray-50 dark:hover:b
<span <span
class="text-sm font-bold text-gray-800 dark:text-gray-200">{{ $customer->name }}</span> class="text-sm font-bold text-gray-800 dark:text-gray-200">{{ $customer->name }}</span>
<span <span
class="text-xs text-gray-400 tracking-tight">{{ $customer->phone ?? 'Telp tidak ada' }}</span> class="text-xs text-gray-400 tracking-tight">{{ $customer->phone_number ?? 'Telp tidak ada' }}</span>
</div> </div>
<div class="text-right"> <div class="text-right">
<span <span