## Summary <!-- Kurz: Was ändert sich und warum? --> ## Spec-Driven Development (SDD) - [ ] Es gibt eine Spec unter `specs/<NNN>-<feature>/` - [ ] Enthaltene Dateien: `plan.md`, `tasks.md`, `spec.md` - [ ] Spec beschreibt Verhalten/Acceptance Criteria (nicht nur Implementation) - [ ] Wenn sich Anforderungen während der Umsetzung geändert haben: Spec/Plan/Tasks wurden aktualisiert ## Implementation - [ ] Implementierung entspricht der Spec - [ ] Edge cases / Fehlerfälle berücksichtigt - [ ] Keine unbeabsichtigten Änderungen außerhalb des Scopes ## Tests - [ ] Tests ergänzt/aktualisiert (Pest/PHPUnit) - [ ] Relevante Tests lokal ausgeführt (`./vendor/bin/sail artisan test` oder `php artisan test`) ## Migration / Config / Ops (falls relevant) - [ ] Migration(en) enthalten und getestet - [ ] Rollback bedacht (rückwärts kompatibel, sichere Migration) - [ ] Neue Env Vars dokumentiert (`.env.example` / Doku) - [ ] Queue/cron/storage Auswirkungen geprüft ## UI (Filament/Livewire) (falls relevant) - [ ] UI-Flows geprüft - [ ] Screenshots/Notizen hinzugefügt ## Notes <!-- Links, Screenshots, Follow-ups, offene Punkte --> Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local> Reviewed-on: #3
139 lines
7.2 KiB
PHP
139 lines
7.2 KiB
PHP
@php
|
|
$general = $getState();
|
|
$entries = is_array($general) ? ($general['entries'] ?? []) : [];
|
|
$cards = [];
|
|
|
|
foreach ($entries as $entry) {
|
|
if (! is_array($entry)) {
|
|
continue;
|
|
}
|
|
|
|
$key = $entry['key'] ?? null;
|
|
$value = $entry['value'] ?? null;
|
|
$decoded = null;
|
|
|
|
if (is_string($value)) {
|
|
$trimmed = trim($value);
|
|
|
|
if ($trimmed !== '' && (str_starts_with($trimmed, '{') || str_starts_with($trimmed, '['))) {
|
|
$decodedValue = json_decode($trimmed, true);
|
|
|
|
if (json_last_error() === JSON_ERROR_NONE) {
|
|
$decoded = $decodedValue;
|
|
$value = $decodedValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
$isEmpty = $value === null
|
|
|| $value === ''
|
|
|| $value === '-'
|
|
|| (is_array($value) && $value === []);
|
|
|
|
if ($isEmpty) {
|
|
continue;
|
|
}
|
|
|
|
$label = is_string($key) && $key !== '' ? $key : 'Field';
|
|
|
|
$cards[] = [
|
|
'key' => $label,
|
|
'key_lower' => strtolower($label),
|
|
'value' => $value,
|
|
'decoded' => $decoded,
|
|
];
|
|
}
|
|
|
|
$toneMap = [
|
|
'name' => ['icon' => 'heroicon-o-tag', 'ring' => 'ring-amber-200/70 dark:ring-amber-800/60', 'tone' => 'amber'],
|
|
'platform' => ['icon' => 'heroicon-o-computer-desktop', 'ring' => 'ring-sky-200/70 dark:ring-sky-800/60', 'tone' => 'sky'],
|
|
'settings' => ['icon' => 'heroicon-o-adjustments-horizontal', 'ring' => 'ring-emerald-200/70 dark:ring-emerald-800/60', 'tone' => 'emerald'],
|
|
'template' => ['icon' => 'heroicon-o-rectangle-stack', 'ring' => 'ring-rose-200/70 dark:ring-rose-800/60', 'tone' => 'rose'],
|
|
'technology' => ['icon' => 'heroicon-o-cpu-chip', 'ring' => 'ring-teal-200/70 dark:ring-teal-800/60', 'tone' => 'teal'],
|
|
'default' => ['icon' => 'heroicon-o-document-text', 'ring' => 'ring-gray-200/70 dark:ring-gray-700/60', 'tone' => 'slate'],
|
|
];
|
|
|
|
$toneClasses = [
|
|
'amber' => 'bg-amber-100/80 text-amber-700 dark:bg-amber-900/40 dark:text-amber-200',
|
|
'sky' => 'bg-sky-100/80 text-sky-700 dark:bg-sky-900/40 dark:text-sky-200',
|
|
'emerald' => 'bg-emerald-100/80 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-200',
|
|
'rose' => 'bg-rose-100/80 text-rose-700 dark:bg-rose-900/40 dark:text-rose-200',
|
|
'teal' => 'bg-teal-100/80 text-teal-700 dark:bg-teal-900/40 dark:text-teal-200',
|
|
'slate' => 'bg-slate-100/80 text-slate-700 dark:bg-slate-900/40 dark:text-slate-200',
|
|
];
|
|
@endphp
|
|
|
|
@if (empty($cards))
|
|
<p class="text-sm text-gray-600 dark:text-gray-400">No general metadata available.</p>
|
|
@else
|
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
|
|
@foreach ($cards as $entry)
|
|
@php
|
|
$keyLower = $entry['key_lower'] ?? '';
|
|
$value = $entry['value'] ?? null;
|
|
$isPlatform = str_contains($keyLower, 'platform');
|
|
$toneKey = match (true) {
|
|
str_contains($keyLower, 'name') => 'name',
|
|
str_contains($keyLower, 'platform') => 'platform',
|
|
str_contains($keyLower, 'setting') => 'settings',
|
|
str_contains($keyLower, 'template') => 'template',
|
|
str_contains($keyLower, 'technology') => 'technology',
|
|
default => 'default',
|
|
};
|
|
$tone = $toneMap[$toneKey] ?? $toneMap['default'];
|
|
$toneClass = $toneClasses[$tone['tone'] ?? 'slate'] ?? $toneClasses['slate'];
|
|
|
|
$isJsonValue = is_array($value) && ! (array_is_list($value) && array_reduce($value, fn ($carry, $item) => $carry && is_scalar($item), true));
|
|
$isListValue = is_array($value) && array_is_list($value) && array_reduce($value, fn ($carry, $item) => $carry && is_scalar($item), true);
|
|
$isBooleanValue = is_bool($value);
|
|
$isBooleanString = is_string($value) && in_array(strtolower($value), ['true', 'false', 'enabled', 'disabled'], true);
|
|
$isNumericValue = is_numeric($value);
|
|
@endphp
|
|
|
|
<div class="tp-policy-general-card group relative overflow-hidden rounded-xl border border-gray-200/70 bg-white p-4 shadow-sm transition duration-200 hover:-translate-y-0.5 hover:border-gray-300/70 hover:shadow-md dark:border-gray-700/60 dark:bg-gray-900 dark:hover:border-gray-600">
|
|
<div class="flex items-start gap-3">
|
|
<div class="flex h-10 w-10 items-center justify-center rounded-lg ring-1 {{ $tone['ring'] ?? '' }} {{ $toneClass }}">
|
|
<x-filament::icon icon="{{ $tone['icon'] ?? 'heroicon-o-document-text' }}" class="h-5 w-5" />
|
|
</div>
|
|
<div class="min-w-0 flex-1">
|
|
<dt class="text-xs font-semibold tracking-wide text-gray-500 dark:text-gray-400">
|
|
{{ $entry['key'] ?? '-' }}
|
|
</dt>
|
|
<dd class="mt-2 text-left">
|
|
@if ($isListValue)
|
|
<div class="flex flex-wrap gap-2">
|
|
@foreach ($value as $item)
|
|
<x-filament::badge :color="$isPlatform ? 'info' : 'gray'" size="sm">
|
|
{{ $item }}
|
|
</x-filament::badge>
|
|
@endforeach
|
|
</div>
|
|
@elseif ($isJsonValue)
|
|
<pre class="whitespace-pre-wrap rounded-lg border border-gray-200 bg-gray-50 p-2 text-xs font-mono text-gray-700 dark:border-gray-700 dark:bg-gray-900/60 dark:text-gray-200">{{ json_encode($value, JSON_PRETTY_PRINT) }}</pre>
|
|
@elseif ($isBooleanValue || $isBooleanString)
|
|
@php
|
|
$boolValue = $isBooleanValue
|
|
? $value
|
|
: in_array(strtolower($value), ['true', 'enabled'], true);
|
|
$boolLabel = $boolValue ? 'Enabled' : 'Disabled';
|
|
@endphp
|
|
<x-filament::badge :color="$boolValue ? 'success' : 'gray'" size="sm">
|
|
{{ $boolLabel }}
|
|
</x-filament::badge>
|
|
@elseif ($isNumericValue)
|
|
<div class="text-sm font-semibold text-gray-900 dark:text-white tabular-nums">
|
|
{{ number_format((float) $value) }}
|
|
</div>
|
|
@else
|
|
<div class="text-sm text-gray-900 dark:text-white whitespace-pre-wrap break-words text-left">
|
|
{{ is_string($value) ? $value : json_encode($value, JSON_PRETTY_PRINT) }}
|
|
</div>
|
|
@endif
|
|
</dd>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|