refactor: restructure DataChangeInfolist to use Section component for improved organization and readability

This commit is contained in:
Yoga Pangestu 2026-04-09 08:30:14 +07:00
parent 30d8432cf5
commit 1ae4d58b48

View File

@ -5,6 +5,7 @@
use App\Filament\Support\CheerfulNotification; use App\Filament\Support\CheerfulNotification;
use App\Models\DataChangeRequest; use App\Models\DataChangeRequest;
use Filament\Infolists\Components\TextEntry; use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
@ -14,109 +15,111 @@ public static function configure(Schema $schema): Schema
{ {
return $schema return $schema
->schema([ ->schema([
TextEntry::make('comparison') Section::make()
->hiddenLabel() ->schema([
->html() TextEntry::make('comparison')
->state(function (DataChangeRequest $record): string { ->hiddenLabel()
$old = $record->old_data ?? []; ->html()
$new = $record->new_data ?? []; ->state(function (DataChangeRequest $record): string {
$old = $record->old_data ?? [];
$new = $record->new_data ?? [];
if (! is_array($old) || ! is_array($new)) { if (! is_array($old) || ! is_array($new)) {
return '<em>Format data tidak valid.</em>'; return '<em>Format data tidak valid.</em>';
}
$renderValue = function ($value) {
if (empty($value)) {
return '<em>Kosong</em>';
}
$paths = is_array($value) ? $value : [$value];
$isProbablyPath = false;
foreach ($paths as $path) {
if (is_string($path) && (str_contains($path, '/') || str_contains($path, '\\'))) {
$isProbablyPath = true;
break;
} }
}
if ($isProbablyPath) { $renderValue = function ($value) {
return collect($paths) if (empty($value)) {
->map(function ($path) { return '<em>Kosong</em>';
if (! is_string($path)) { }
return e(json_encode($path));
$paths = is_array($value) ? $value : [$value];
$isProbablyPath = false;
foreach ($paths as $path) {
if (is_string($path) && (str_contains($path, '/') || str_contains($path, '\\'))) {
$isProbablyPath = true;
break;
} }
}
$url = Storage::disk(config('filesystems.default'))->url($path); if ($isProbablyPath) {
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION)); return collect($paths)
->map(function ($path) {
if (! is_string($path)) {
return e(json_encode($path));
}
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) { $url = Storage::disk(config('filesystems.default'))->url($path);
return "<a href='{$url}' target='_blank'><img src='{$url}' style='max-height:100px; border-radius:8px; margin-top:4px; border:1px solid #e5e7eb;'></a>"; $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
}
if ($extension === 'pdf') { if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) {
return " return "<a href='{$url}' target='_blank'><img src='{$url}' style='max-height:100px; border-radius:8px; margin-top:4px; border:1px solid #e5e7eb;'></a>";
}
if ($extension === 'pdf') {
return "
<div style='margin-top:4px;'> <div style='margin-top:4px;'>
<iframe src='{$url}' style='width:100%; height:300px; border:1px solid #e5e7eb; border-radius:8px;'></iframe> <iframe src='{$url}' style='width:100%; height:300px; border:1px solid #e5e7eb; border-radius:8px;'></iframe>
<a href='{$url}' target='_blank' style='display:block; margin-top:4px; color:#3b82f6; text-decoration:underline; font-size:0.75rem;'>↗️ Buka PDF di Tab Baru</a> <a href='{$url}' target='_blank' style='display:block; margin-top:4px; color:#3b82f6; text-decoration:underline; font-size:0.75rem;'>↗️ Buka PDF di Tab Baru</a>
</div> </div>
"; ";
} }
return "<a href='{$url}' target='_blank' style='color:#3b82f6; text-decoration:underline; font-size:0.875rem;'>📎 Buka Dokumen (".strtoupper($extension).')</a>'; return "<a href='{$url}' target='_blank' style='color:#3b82f6; text-decoration:underline; font-size:0.875rem;'>📎 Buka Dokumen (".strtoupper($extension).')</a>';
}) })
->implode('<br>'); ->implode('<br>');
} }
return e(is_scalar($value) ? $value : json_encode($value)); return e(is_scalar($value) ? $value : json_encode($value));
}; };
// 1. Deletion Request // 1. Deletion Request
if (isset($new['__delete_request__']) && $new['__delete_request__'] === true) { if (isset($new['__delete_request__']) && $new['__delete_request__'] === true) {
return " return "
<div style='background-color:#fee2e2; border:1px solid #f87171; color:#991b1b; padding:16px; border-radius:8px; margin-bottom:16px;'> <div style='background-color:#fee2e2; border:1px solid #f87171; color:#991b1b; padding:16px; border-radius:8px; margin-bottom:16px;'>
<div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>".CheerfulNotification::getByKey('data_change.deletion_request_title')."</div> <div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>".CheerfulNotification::getByKey('data_change.deletion_request_title')."</div>
<p style='font-size:0.875rem;'>".CheerfulNotification::getByKey('data_change.deletion_request_desc').'</p> <p style='font-size:0.875rem;'>".CheerfulNotification::getByKey('data_change.deletion_request_desc').'</p>
</div> </div>
'; ';
} }
// 2. New Addition Request // 2. New Addition Request
if (empty($old)) { if (empty($old)) {
$rows = collect($new) $rows = collect($new)
->map(function ($value, $key) use ($renderValue) { ->map(function ($value, $key) use ($renderValue) {
return sprintf( return sprintf(
"<div style='margin-bottom:12px; border-bottom:1px solid #f3f4f6; padding-bottom:8px'> "<div style='margin-bottom:12px; border-bottom:1px solid #f3f4f6; padding-bottom:8px'>
<div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div> <div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div>
<div style='color:#16a34a; font-weight:500;'>[BARU]</div> <div style='color:#16a34a; font-weight:500;'>[BARU]</div>
<div style='margin-top:4px'>%s</div> <div style='margin-top:4px'>%s</div>
</div>", </div>",
e($key), e($key),
$renderValue($value) $renderValue($value)
); );
}) })
->implode(''); ->implode('');
return " return "
<div style='background-color:#f0fdf4; border:1px solid #bbf7d0; color:#166534; padding:16px; border-radius:8px; margin-bottom:16px;'> <div style='background-color:#f0fdf4; border:1px solid #bbf7d0; color:#166534; padding:16px; border-radius:8px; margin-bottom:16px;'>
<div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>".CheerfulNotification::getByKey('data_change.addition_request_title')."</div> <div style='font-weight:700; font-size:1.125rem; margin-bottom:4px;'>".CheerfulNotification::getByKey('data_change.addition_request_title')."</div>
<p style='font-size:0.875rem;'>".CheerfulNotification::getByKey('data_change.addition_request_desc')."</p> <p style='font-size:0.875rem;'>".CheerfulNotification::getByKey('data_change.addition_request_desc')."</p>
</div> </div>
{$rows} {$rows}
"; ";
}
// 3. Standard Comparison (Update)
return collect($new)
->map(function ($newValue, $key) use ($old, $renderValue) {
$oldValue = $old[$key] ?? null;
if ($oldValue === $newValue) {
return null;
} }
return sprintf( // 3. Standard Comparison (Update)
"<div style='margin-bottom:16px; border-bottom:1px solid #f3f4f6; padding-bottom:12px'> return collect($new)
->map(function ($newValue, $key) use ($old, $renderValue) {
$oldValue = $old[$key] ?? null;
if ($oldValue === $newValue) {
return null;
}
return sprintf(
"<div style='margin-bottom:16px; border-bottom:1px solid #f3f4f6; padding-bottom:12px'>
<div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div> <div style='font-weight:600; color:#374151; margin-bottom:4px'>%s</div>
<div style='display:grid; grid-template-columns: 1fr 1fr; gap:16px'> <div style='display:grid; grid-template-columns: 1fr 1fr; gap:16px'>
<div> <div>
@ -129,15 +132,15 @@ public static function configure(Schema $schema): Schema
</div> </div>
</div> </div>
</div>", </div>",
e($key), e($key),
$renderValue($oldValue), $renderValue($oldValue),
$renderValue($newValue) $renderValue($newValue)
); );
}) })
->filter() ->filter()
->implode(''); ->implode('');
}) }),
->columnSpanFull(), ]),
]) ])
->columns(1); ->columns(1);
} }