Implement auto-save feature and sticky header in EditPage: Added auto-save functionality with silent notifications for successful saves, enhancing user experience. Introduced a new Blade view for sticky header and footer, ensuring accessibility of actions during editing. Updated custom block rendering to support markdown formatting.

This commit is contained in:
Ümit Tunç
2025-10-30 17:38:17 -03:00
parent d5458ec0e3
commit 0f78292c46
3 changed files with 101 additions and 1 deletions
@@ -9,19 +9,45 @@ use Filament\Actions\DeleteAction;
use Filament\Actions\ForceDeleteAction;
use Filament\Actions\RestoreAction;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Contracts\View\View;
class EditPage extends EditRecord
{
protected static string $resource = PageResource::class;
// Sticky header aktif
protected static bool $hasTopbar = true;
public bool $autoSaveEnabled = false;
public ?string $lastAutoSaveTime = null;
public function getTitle(): string
{
return __('pages.edit');
}
public function autoSave(): void
{
try {
$this->save();
$this->lastAutoSaveTime = now()->format('H:i:s');
// Sessiz başarı bildirimi
\Filament\Notifications\Notification::make()
->title('Otomatik Kaydedildi')
->body('Son kayıt: ' . $this->lastAutoSaveTime)
->success()
->duration(2000)
->send();
} catch (\Exception $e) {
// Hata olursa sessizce geç, kullanıcıyı rahatsız etme
}
}
protected function getHeaderActions(): array
{
return [
Action::make('save')
->label(__('pages.save'))
->action('save')
@@ -125,4 +151,11 @@ class EditPage extends EditRecord
// Save translations
TranslationTabs::saveTranslations($this->record, $this->form->getState());
}
public function getFooter(): ?View
{
return view('filament.pages.edit-page-footer', [
'autoSaveEnabled' => $this->autoSaveEnabled,
]);
}
}
@@ -1,3 +1,9 @@
@foreach($data as $item)
{!! $item['value'] !!}
@if(($item['type'] ?? null) === 'markdown')
<div class="container">
{!! \Illuminate\Support\Str::markdown($item['value']) !!}
</div>
@else
{!! $item['value'] !!}
@endif
@endforeach
@@ -0,0 +1,61 @@
{{-- Sticky Header CSS --}}
<style>
/* Header'ı sticky yap */
.fi-topbar {
position: sticky !important;
top: 0 !important;
z-index: 40 !important;
background: white !important;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1) !important;
}
/* Dark mode için */
.dark .fi-topbar {
background: rgb(17 24 39) !important;
}
/* Page header'ı da sticky yap */
.fi-header {
position: sticky !important;
top: 0 !important;
z-index: 39 !important;
background: white !important;
padding-top: 1rem !important;
padding-bottom: 1rem !important;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1) !important;
}
/* Dark mode için */
.dark .fi-header {
background: rgb(17 24 39) !important;
}
/* Sidebar varsa topbar'ın pozisyonunu ayarla */
@media (min-width: 1024px) {
.fi-sidebar-open .fi-topbar {
left: 0 !important;
}
}
</style>
@if($autoSaveEnabled)
{{-- Otomatik Kaydetme Script --}}
<div x-data="{
autoSaveInterval: null,
init() {
// Her 30 saniyede bir otomatik kaydet
this.autoSaveInterval = setInterval(() => {
$wire.autoSave();
}, 30000); // 30 saniye (30000 ms)
},
destroy() {
// Sayfa kapanırken interval'i temizle
if (this.autoSaveInterval) {
clearInterval(this.autoSaveInterval);
}
}
}" class="hidden">
<!-- Otomatik kaydetme aktif: Her 30 saniyede bir -->
</div>
@endif