feat(app-ui): 組合內容設定頁依類別群組分塊+分隔線(A系列/E系列/P系列)
config 加 groups 定義(標題+順序);content 頁 groupBy group 渲染,塊間加 hr Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
de3723bb1e
commit
b3d4760b55
@ -20,6 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
// 群組定義(決定內容設定頁的分塊標題與順序;未列到的群組排最後)
|
||||||
|
'groups' => [
|
||||||
|
'fullscreen' => '滿版畫面(A 系列)',
|
||||||
|
'transaction' => '交易結果(E 系列)',
|
||||||
|
'payment' => '支付方式(P 系列)',
|
||||||
|
],
|
||||||
|
|
||||||
'parts' => [
|
'parts' => [
|
||||||
// === A 系列:滿版 / 大圖背景 ===
|
// === A 系列:滿版 / 大圖背景 ===
|
||||||
'A1' => ['label' => 'A1 - 頁面跳轉中', 'group' => 'fullscreen', 'type' => 'image', 'width' => 1080, 'height' => 1920, 'active' => true],
|
'A1' => ['label' => 'A1 - 頁面跳轉中', 'group' => 'fullscreen', 'type' => 'image', 'width' => 1080, 'height' => 1920, 'active' => true],
|
||||||
|
|||||||
@ -15,34 +15,52 @@
|
|||||||
<form action="{{ route('admin.app.ui-bundles.content.update', $bundle) }}" method="POST">
|
<form action="{{ route('admin.app.ui-bundles.content.update', $bundle) }}" method="POST">
|
||||||
@csrf @method('PUT')
|
@csrf @method('PUT')
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
@php
|
||||||
@foreach($parts as $key => $part)
|
$grouped = collect($parts)->groupBy('group', true);
|
||||||
@php
|
$groupDefs = config('ui_parts.groups', []);
|
||||||
$currentId = optional($itemsByPart->get($key))->ui_element_id;
|
// 群組順序:先照 config 定義,未定義者排最後,且只留實際有部位的群組
|
||||||
$currentThumb = optional(optional($itemsByPart->get($key))->element)->image_url ?? '';
|
$orderedGroups = collect($groupDefs)->keys()
|
||||||
@endphp
|
->merge($grouped->keys())->unique()
|
||||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-100 dark:border-gray-700 p-4" x-data="{ thumb: @js($currentThumb) }">
|
->filter(fn($g) => $grouped->has($g))->values();
|
||||||
<label class="block text-sm font-semibold text-gray-800 dark:text-gray-100 mb-2">
|
$firstGroup = true;
|
||||||
{{ $part['label'] }}
|
@endphp
|
||||||
@if($part['width'])<span class="text-xs font-normal text-gray-400">({{ $part['width'] }}x{{ $part['height'] }})</span>@endif
|
|
||||||
</label>
|
@foreach($orderedGroups as $groupKey)
|
||||||
<select name="parts[{{ $key }}]"
|
@if(!$firstGroup)
|
||||||
@change="thumb = ($event.target.selectedOptions[0]?.dataset.thumb) || ''"
|
<hr class="my-8 border-t border-gray-200 dark:border-gray-700">
|
||||||
class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 text-sm focus:ring-2 focus:ring-cyan-500">
|
@endif
|
||||||
<option value="">{{ __('Not set') }}</option>
|
@php $firstGroup = false; @endphp
|
||||||
@foreach($elementsByPart[$key] as $element)
|
|
||||||
<option value="{{ $element->id }}" data-thumb="{{ $element->image_url }}" {{ (string)$currentId === (string)$element->id ? 'selected' : '' }}>
|
<h4 class="text-base font-semibold text-gray-800 dark:text-gray-200 mb-3">{{ $groupDefs[$groupKey] ?? $groupKey }}</h4>
|
||||||
{{ $element->name }}
|
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
||||||
</option>
|
@foreach($grouped[$groupKey] as $key => $part)
|
||||||
@endforeach
|
@php
|
||||||
</select>
|
$currentId = optional($itemsByPart->get($key))->ui_element_id;
|
||||||
<div class="mt-3">
|
$currentThumb = optional(optional($itemsByPart->get($key))->element)->image_url ?? '';
|
||||||
<img x-show="thumb" x-cloak :src="thumb" class="h-28 w-auto max-w-full object-contain rounded border border-gray-200 dark:border-gray-700 bg-gray-50">
|
@endphp
|
||||||
<p x-show="!thumb" x-cloak class="text-xs text-gray-400">{{ __('No image selected') }}</p>
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-100 dark:border-gray-700 p-4" x-data="{ thumb: @js($currentThumb) }">
|
||||||
|
<label class="block text-sm font-semibold text-gray-800 dark:text-gray-100 mb-2">
|
||||||
|
{{ $part['label'] }}
|
||||||
|
@if($part['width'])<span class="text-xs font-normal text-gray-400">({{ $part['width'] }}x{{ $part['height'] }})</span>@endif
|
||||||
|
</label>
|
||||||
|
<select name="parts[{{ $key }}]"
|
||||||
|
@change="thumb = ($event.target.selectedOptions[0]?.dataset.thumb) || ''"
|
||||||
|
class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 text-sm focus:ring-2 focus:ring-cyan-500">
|
||||||
|
<option value="">{{ __('Not set') }}</option>
|
||||||
|
@foreach($elementsByPart[$key] as $element)
|
||||||
|
<option value="{{ $element->id }}" data-thumb="{{ $element->image_url }}" {{ (string)$currentId === (string)$element->id ? 'selected' : '' }}>
|
||||||
|
{{ $element->name }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<div class="mt-3">
|
||||||
|
<img x-show="thumb" x-cloak :src="thumb" class="h-28 w-auto max-w-full object-contain rounded border border-gray-200 dark:border-gray-700 bg-gray-50">
|
||||||
|
<p x-show="!thumb" x-cloak class="text-xs text-gray-400">{{ __('No image selected') }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endforeach
|
||||||
@endforeach
|
</div>
|
||||||
</div>
|
@endforeach
|
||||||
|
|
||||||
<div class="mt-6 flex justify-end">
|
<div class="mt-6 flex justify-end">
|
||||||
<button type="submit" class="btn-luxury-primary">{{ __('Save') }}</button>
|
<button type="submit" class="btn-luxury-primary">{{ __('Save') }}</button>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user