198 lines
8.2 KiB
PHP
198 lines
8.2 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\Manage\DataChanges\Infolists;
|
|
|
|
use App\Filament\Support\CheerfulNotification;
|
|
use App\Models\DataChangeRequest;
|
|
use Filament\Infolists\Components\ImageEntry;
|
|
use Filament\Infolists\Components\TextEntry;
|
|
use Filament\Schemas\Components\Grid;
|
|
use Filament\Schemas\Components\Section;
|
|
use Filament\Schemas\Schema;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Joaopaulolndev\FilamentPdfViewer\Infolists\Components\PdfViewerEntry;
|
|
|
|
class DataChangeInfolist
|
|
{
|
|
public static function configure(Schema $schema): Schema
|
|
{
|
|
return $schema
|
|
->schema(function (DataChangeRequest $record): array {
|
|
$old = $record->old_data ?? [];
|
|
$new = $record->new_data ?? [];
|
|
|
|
if (! is_array($old) || ! is_array($new)) {
|
|
return [
|
|
TextEntry::make('error')
|
|
->hiddenLabel()
|
|
->state('Format data tidak valid.')
|
|
->badge()
|
|
->color('danger'),
|
|
];
|
|
}
|
|
|
|
if (empty($new)) {
|
|
return self::buildDeletionView($old);
|
|
}
|
|
|
|
if (empty($old)) {
|
|
return self::buildAdditionView($new);
|
|
}
|
|
|
|
return self::buildUpdateView($old, $new);
|
|
})
|
|
->columns(1);
|
|
}
|
|
|
|
private static function buildDeletionView(array $old): array
|
|
{
|
|
$title = CheerfulNotification::getByKey('data_change.deletion_request_title');
|
|
$desc = CheerfulNotification::getByKey('data_change.deletion_request_desc');
|
|
|
|
return [
|
|
Section::make($title)
|
|
->description($desc)
|
|
->icon('heroicon-o-trash')
|
|
->schema([
|
|
TextEntry::make('badge')->hiddenLabel()->state('Penghapusan')->badge()->color('danger'),
|
|
...collect($old)->map(fn ($v, $k) => self::fieldEntry($k, $v, showLabel: true))->flatten()->toArray(),
|
|
]),
|
|
];
|
|
}
|
|
|
|
private static function buildAdditionView(array $new): array
|
|
{
|
|
$title = CheerfulNotification::getByKey('data_change.addition_request_title');
|
|
$desc = CheerfulNotification::getByKey('data_change.addition_request_desc');
|
|
|
|
return [
|
|
Section::make($title)
|
|
->description($desc)
|
|
->icon('heroicon-o-plus-circle')
|
|
->schema([
|
|
TextEntry::make('badge')->hiddenLabel()->state('Penambahan Baru')->badge()->color('success'),
|
|
...collect($new)->map(fn ($v, $k) => self::fieldEntry($k, $v, showLabel: true))->flatten()->toArray(),
|
|
]),
|
|
];
|
|
}
|
|
|
|
private static function buildUpdateView(array $old, array $new): array
|
|
{
|
|
$title = CheerfulNotification::getByKey('data_change.comparison_title');
|
|
$desc = CheerfulNotification::getByKey('data_change.comparison_desc');
|
|
|
|
$changedFields = collect($new)
|
|
->filter(fn ($newVal, $key) => ($old[$key] ?? null) !== $newVal);
|
|
|
|
if ($changedFields->isEmpty()) {
|
|
return [
|
|
TextEntry::make('info')->hiddenLabel()->state('Tidak ada perubahan data terdeteksi.')->badge()->color('info'),
|
|
];
|
|
}
|
|
|
|
$fieldCount = $changedFields->count();
|
|
$label = $fieldCount === 1 ? '1 field diubah' : "{$fieldCount} field diubah";
|
|
|
|
return [
|
|
Section::make($title)
|
|
->description($desc)
|
|
->icon('heroicon-o-pencil-square')
|
|
->schema([
|
|
TextEntry::make('badge')->hiddenLabel()->state($label)->badge()->color('primary'),
|
|
Grid::make(1)
|
|
->schema(
|
|
$changedFields->map(function ($newVal, $key) use ($old) {
|
|
$oldVal = $old[$key] ?? null;
|
|
|
|
return [
|
|
Section::make($key)
|
|
->columnSpanFull()
|
|
->compact()
|
|
->schema([
|
|
Grid::make(2)
|
|
->schema([
|
|
Grid::make(1)
|
|
->schema([
|
|
TextEntry::make("{$key}_old_label")
|
|
->hiddenLabel()
|
|
->state('SEBELUM')
|
|
->weight('bold')
|
|
->size('xs')
|
|
->color('danger'),
|
|
...self::fieldEntry("{$key}_old", $oldVal, showLabel: false),
|
|
])->columnSpan(1),
|
|
|
|
Grid::make(1)
|
|
->schema([
|
|
TextEntry::make("{$key}_new_label")
|
|
->hiddenLabel()
|
|
->state('SESUDAH')
|
|
->weight('bold')
|
|
->size('xs')
|
|
->color('success'),
|
|
...self::fieldEntry("{$key}_new", $newVal, showLabel: false),
|
|
])->columnSpan(1),
|
|
]),
|
|
]),
|
|
];
|
|
})->flatten()->toArray()
|
|
),
|
|
]),
|
|
];
|
|
}
|
|
|
|
private static function fieldEntry(string $label, mixed $value, bool $showLabel = true): array
|
|
{
|
|
$id = str($label)->slug('_')->toString();
|
|
|
|
if ($value === null || $value === '' || (is_array($value) && empty($value))) {
|
|
return [
|
|
TextEntry::make($id)
|
|
->label($label)
|
|
->hiddenLabel(! $showLabel)
|
|
->state('—')
|
|
->color('gray'),
|
|
];
|
|
}
|
|
|
|
$paths = is_array($value) ? $value : [$value];
|
|
$components = [];
|
|
|
|
foreach ($paths as $index => $item) {
|
|
$uniqueId = "{$id}_{$index}";
|
|
|
|
if (is_string($item) && (str_contains($item, '/') || str_contains($item, '\\'))) {
|
|
$ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
|
|
|
|
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) {
|
|
$components[] = ImageEntry::make($uniqueId)
|
|
->label($index === 0 ? $label : '')
|
|
->hiddenLabel(! ($showLabel && $index === 0))
|
|
->disk(config('filesystems.default'))
|
|
->state($item)
|
|
->extraImgAttributes(['style' => 'max-height: 200px; width: auto; border-radius: 0.5rem;']);
|
|
|
|
continue;
|
|
}
|
|
|
|
if ($ext === 'pdf') {
|
|
$components[] = PdfViewerEntry::make($uniqueId)
|
|
->label($index === 0 ? $label : '')
|
|
->hiddenLabel(! ($showLabel && $index === 0))
|
|
->minHeight('500px')
|
|
->state(Storage::disk(config('filesystems.default'))->url($item));
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$components[] = TextEntry::make($uniqueId)
|
|
->label($index === 0 ? $label : '')
|
|
->hiddenLabel(! ($showLabel && $index === 0))
|
|
->state(is_scalar($item) ? $item : json_encode($item));
|
|
}
|
|
|
|
return $components;
|
|
}
|
|
}
|