169 lines
No EOL
7.3 KiB
PHP
169 lines
No EOL
7.3 KiB
PHP
<div class="space-y-6">
|
|
{{-- Page Header --}}
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<h1 class="text-2xl font-semibold text-gray-900">
|
|
{{ $editingPage ? 'Edit Page' : 'Create Page' }}
|
|
</h1>
|
|
@if($editingPage)
|
|
<p class="text-sm text-gray-500 mt-1">
|
|
Last updated {{ $editingPage->updated_at->diffForHumans() }}
|
|
</p>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="flex items-center space-x-3">
|
|
@if($editingPage && $editingPage->is_published)
|
|
<flux:badge color="green" size="sm">Published</flux:badge>
|
|
@elseif($editingPage)
|
|
<flux:badge color="yellow" size="sm">Draft</flux:badge>
|
|
@endif
|
|
|
|
<flux:button wire:click="save" variant="primary">
|
|
{{ $editingPage ? 'Update' : 'Create' }} Page
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Page Settings --}}
|
|
<flux:card>
|
|
<flux:card.header>
|
|
<flux:heading size="lg">Page Settings</flux:heading>
|
|
</flux:card.header>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
{{-- Basic Information --}}
|
|
<div class="space-y-4">
|
|
<flux:field>
|
|
<flux:label>Title</flux:label>
|
|
<flux:input wire:model.live="pageData.title" placeholder="Enter page title" />
|
|
<flux:error name="pageData.title" />
|
|
</flux:field>
|
|
|
|
<flux:field>
|
|
<flux:label>Slug</flux:label>
|
|
<flux:input wire:model.live="pageData.slug" placeholder="page-url-slug" />
|
|
<flux:error name="pageData.slug" />
|
|
</flux:field>
|
|
|
|
<flux:field>
|
|
<flux:label>Template</flux:label>
|
|
<flux:select wire:model.live="pageData.template" placeholder="Select template">
|
|
@foreach($availableTemplates as $template)
|
|
<flux:option value="{{ $template }}">{{ $template }}</flux:option>
|
|
@endforeach
|
|
</flux:select>
|
|
<flux:error name="pageData.template" />
|
|
</flux:field>
|
|
</div>
|
|
|
|
{{-- SEO & Publishing --}}
|
|
<div class="space-y-4">
|
|
<flux:field>
|
|
<flux:label>Meta Title</flux:label>
|
|
<flux:input wire:model.live="pageData.meta_title" placeholder="SEO title" />
|
|
<flux:error name="pageData.meta_title" />
|
|
</flux:field>
|
|
|
|
<flux:field>
|
|
<flux:label>Meta Description</flux:label>
|
|
<flux:textarea wire:model.live="pageData.meta_description" placeholder="SEO description" rows="3" />
|
|
<flux:error name="pageData.meta_description" />
|
|
</flux:field>
|
|
|
|
<div class="flex items-center space-x-4">
|
|
<flux:field>
|
|
<flux:checkbox wire:model.live="pageData.is_published">
|
|
Published
|
|
</flux:checkbox>
|
|
</flux:field>
|
|
|
|
<flux:field>
|
|
<flux:checkbox wire:model.live="pageData.show_in_navigation">
|
|
Show in Navigation
|
|
</flux:checkbox>
|
|
</flux:field>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
|
|
{{-- Page Components --}}
|
|
<flux:card>
|
|
<flux:card.header>
|
|
<div class="flex items-center justify-between">
|
|
<flux:heading size="lg">Page Components</flux:heading>
|
|
<flux:button wire:click="$dispatch('open-component-modal')" size="sm">
|
|
Add Component
|
|
</flux:button>
|
|
</div>
|
|
</flux:card.header>
|
|
|
|
<div class="space-y-4" wire:sortable="updateComponentOrder">
|
|
@forelse($components as $index => $component)
|
|
<div wire:sortable.item="{{ $component['id'] }}"
|
|
wire:key="component-{{ $component['id'] }}"
|
|
class="p-4 border border-gray-200 rounded-lg bg-gray-50">
|
|
|
|
<div class="flex items-center justify-between mb-3">
|
|
<div class="flex items-center space-x-3">
|
|
<flux:icon.bars-3 class="w-5 h-5 text-gray-400 cursor-move" wire:sortable.handle />
|
|
<span class="font-medium text-gray-900">
|
|
{{ $component['component_type'] }}
|
|
</span>
|
|
@if(!$component['is_active'])
|
|
<flux:badge color="gray" size="sm">Inactive</flux:badge>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="flex items-center space-x-2">
|
|
<flux:button wire:click="editComponent({{ $index }})" size="sm" variant="ghost">
|
|
Edit
|
|
</flux:button>
|
|
<flux:button wire:click="toggleComponent({{ $index }})" size="sm" variant="ghost">
|
|
{{ $component['is_active'] ? 'Disable' : 'Enable' }}
|
|
</flux:button>
|
|
<flux:button wire:click="removeComponent({{ $index }})" size="sm" variant="danger">
|
|
Remove
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Component Preview --}}
|
|
<div class="text-sm text-gray-600">
|
|
@if(!empty($component['content']['title']))
|
|
<strong>Title:</strong> {{ $component['content']['title'] }}
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="text-center py-8 text-gray-500">
|
|
<flux:icon.puzzle-piece class="w-12 h-12 mx-auto mb-3 text-gray-300" />
|
|
<p>No components added yet.</p>
|
|
<p class="text-sm">Click "Add Component" to get started.</p>
|
|
</div>
|
|
@endforelse
|
|
</div>
|
|
</flux:card>
|
|
|
|
{{-- Component Selection Modal --}}
|
|
<flux:modal name="component-modal" class="md:w-2xl">
|
|
<div class="space-y-6">
|
|
<flux:heading size="lg">Add Component</flux:heading>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
@foreach($availableComponents as $componentClass => $componentInfo)
|
|
<div wire:click="addComponent('{{ $componentClass }}')"
|
|
class="p-4 border border-gray-200 rounded-lg cursor-pointer hover:border-blue-300 hover:bg-blue-50 transition-colors">
|
|
<h3 class="font-medium text-gray-900 mb-2">
|
|
{{ $componentInfo['name'] }}
|
|
</h3>
|
|
<p class="text-sm text-gray-600">
|
|
{{ $componentInfo['description'] ?? 'No description available' }}
|
|
</p>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</flux:modal>
|
|
</div> |