columns([ ...RowIndexColumn::make(), TextColumn::make('date') ->label('Tanggal & Waktu') ->date('l, d F Y') ->sortable(), TextColumn::make('route') ->label('Halaman') ->searchable() ->sortable(), TextColumn::make('method') ->label('Method') ->badge() ->color(fn (string $state): string => match ($state) { 'GET' => 'success', 'POST' => 'warning', default => 'gray', }), TextColumn::make('status') ->label('Status') ->badge() ->color(fn (int $state): string => $state >= 200 && $state < 300 ? 'success' : 'danger'), TextColumn::make('ip') ->label('IP Address') ->searchable(), TextColumn::make('counter') ->label('Hits') ->numeric() ->sortable(), TextColumn::make('user.name') ->label('User') ->placeholder('Tamu'), ]) ->defaultSort('date', 'desc') ->filters([ SelectFilter::make('method') ->options([ 'GET' => 'GET', 'POST' => 'POST', ]) ->native(false), Filter::make('date_filter') ->schema([ Select::make('date_type') ->label('Jenis Filter Tanggal') ->options([ 'date' => 'Tanggal', 'month' => 'Bulan & Tahun', 'year' => 'Tahun', 'range' => 'Rentang Tanggal', ]) ->live() ->native(false), DatePicker::make('specific_date') ->label('Tanggal') ->placeholder('Pilih tanggal') ->visible(fn (Get $get) => $get('date_type') === 'date') ->native(false), Select::make('month') ->label('Bulan') ->options([ 1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April', 5 => 'Mei', 6 => 'Juni', 7 => 'Juli', 8 => 'Agustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember', ]) ->visible(fn (Get $get) => $get('date_type') === 'month') ->native(false), Select::make('year') ->label('Tahun') ->options(function () { $years = range(date('Y'), 2020); return array_combine($years, $years); }) ->visible(fn (Get $get) => in_array($get('date_type'), ['month', 'year'])) ->native(false), DatePicker::make('start_date') ->label('Tanggal Mulai') ->placeholder('Pilih tanggal mulai') ->visible(fn (Get $get) => $get('date_type') === 'range') ->native(false) ->displayFormat('l, d F Y'), DatePicker::make('end_date') ->label('Tanggal Selesai') ->placeholder('Pilih tanggal selesai') ->visible(fn (Get $get) => $get('date_type') === 'range') ->native(false) ->displayFormat('l, d F Y'), ]) ->query(function (Builder $query, array $data): Builder { $type = $data['date_type'] ?? null; $column = 'date'; return $query->when($type, function (Builder $query) use ($type, $data, $column) { if ($type === 'date' && ! empty($data['specific_date'])) { $query->whereDate($column, $data['specific_date']); } elseif ($type === 'month' && ! empty($data['month']) && ! empty($data['year'])) { $query->whereMonth($column, $data['month']) ->whereYear($column, $data['year']); } elseif ($type === 'year' && ! empty($data['year'])) { $query->whereYear($column, $data['year']); } elseif ($type === 'range' && ! empty($data['start_date']) && ! empty($data['end_date'])) { $query->whereBetween($column, [$data['start_date'], $data['end_date']]); } }); }), ], FiltersLayout::AboveContentCollapsible) ->filtersFormColumns(3) ->emptyStateIcon(Heroicon::OutlinedChartBar) ->emptyStateDescription(fn () => CheerfulNotification::getMessage('Belum ada data Pengunjung nih! Mulai buat data pertama sekarang biar makin rame! 🚀✨', 'Belum ada data Pengunjung yang tersedia saat ini.')) ->defaultSort('date', 'desc') ->deferFilters(false) ->paginated([25, 50, 100, 'all']) ->deferLoading(); } public static function getPages(): array { return [ 'index' => ManageVisitors::route('/'), ]; } }