Enhance Page Edit functionality: Implemented conversion of old format sections to a new structured format in the EditPage class, allowing for better data management. Updated PageForm schema to conditionally hydrate fields based on their type, improving the user experience and ensuring proper data handling for various input types.

This commit is contained in:
Ümit Tunç
2025-10-30 16:48:30 -03:00
parent 22b39d94a9
commit 8a58e63259
2 changed files with 155 additions and 11 deletions
@@ -45,6 +45,58 @@ class EditPage extends EditRecord
// Load existing translations // Load existing translations
$translationData = TranslationTabs::fillFromRecord($this->record); $translationData = TranslationTabs::fillFromRecord($this->record);
// Convert old format sections to new format
if (isset($data['sections']) && is_array($data['sections'])) {
$data['sections'] = array_map(function ($section) {
if (!isset($section['data']) || !is_array($section['data'])) {
return $section;
}
// Check if already in new format
$firstKey = array_key_first($section['data']);
if (is_numeric($firstKey) && isset($section['data'][$firstKey]['key'])) {
return $section;
}
// Convert old format to new format
$newData = [];
foreach ($section['data'] as $key => $value) {
$type = 'text'; // Default
// Auto-detect type based on key name and value
if (str_contains($key, 'image') || str_contains($key, 'photo')) {
$type = 'image';
} elseif (str_contains($key, 'icon') && is_string($value) && str_starts_with($value, 'assets/')) {
$type = 'image';
} elseif (str_contains($key, 'color')) {
$type = 'color';
} elseif (str_contains($key, 'url') || str_contains($key, 'link')) {
$type = 'url';
} elseif (is_string($value) && (str_contains($key, 'subtitle') || str_contains($key, 'description'))) {
$type = 'textarea';
} elseif (is_string($value) && str_contains($value, '<') && str_contains($value, '>') && strlen($value) > 200) {
$type = 'html'; // Long HTML content
} elseif (is_string($value) && strlen($value) > 100) {
$type = 'textarea';
} elseif (is_array($value)) {
$type = 'array';
} elseif (is_bool($value)) {
$type = 'boolean';
}
// 'title' gibi kısa HTML snippet'leri 'text' olarak kalır
$newData[] = [
'key' => $key,
'type' => $type,
'value' => $value,
];
}
$section['data'] = $newData;
return $section;
}, $data['sections']);
}
return array_merge($data, $translationData); return array_merge($data, $translationData);
} }
@@ -245,7 +245,16 @@ class PageForm
->placeholder('Değer girin...') ->placeholder('Değer girin...')
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
// Only hydrate if this field type is active
if (!in_array($get('type'), ['text', 'url', 'email', 'phone', 'number'])) {
return;
}
$value = $get('value');
if ($value !== null) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -257,7 +266,16 @@ class PageForm
->placeholder(fn (Get $get) => $get('type') === 'html' ? '<div>HTML kodu girin...</div>' : 'Metin girin...') ->placeholder(fn (Get $get) => $get('type') === 'html' ? '<div>HTML kodu girin...</div>' : 'Metin girin...')
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
// Only hydrate if this field type is active
if (!in_array($get('type'), ['textarea', 'json', 'html'])) {
return;
}
$value = $get('value');
if ($value !== null) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -276,7 +294,33 @@ class PageForm
]) ])
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
// Only hydrate if this field type is richtext
if ($get('type') !== 'richtext') {
return;
}
$value = $get('value');
// Skip if null or empty
if ($value === null || $value === '' || $value === []) {
return;
}
// Only set if it's valid TipTap JSON format
if (is_array($value) && isset($value['type']) && $value['type'] === 'doc') {
$component->state($value);
} elseif (is_string($value)) {
try {
$decoded = json_decode($value, true);
if (is_array($decoded) && isset($decoded['type']) && $decoded['type'] === 'doc') {
$component->state($decoded);
}
} catch (\Exception $e) {
// Invalid JSON, skip
}
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -286,7 +330,13 @@ class PageForm
->visible(fn (Get $get) => $get('type') === 'markdown') ->visible(fn (Get $get) => $get('type') === 'markdown')
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'markdown') return;
$value = $get('value');
if ($value !== null && is_string($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -300,7 +350,13 @@ class PageForm
->imageEditor() ->imageEditor()
->live() ->live()
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'image') return;
$value = $get('value');
if ($value !== null && is_string($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -312,7 +368,13 @@ class PageForm
->directory('pages/sections') ->directory('pages/sections')
->live() ->live()
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'file') return;
$value = $get('value');
if ($value !== null && is_string($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -322,7 +384,13 @@ class PageForm
->visible(fn (Get $get) => $get('type') === 'boolean') ->visible(fn (Get $get) => $get('type') === 'boolean')
->live() ->live()
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'boolean') return;
$value = $get('value');
if ($value !== null && is_bool($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -332,7 +400,13 @@ class PageForm
->visible(fn (Get $get) => $get('type') === 'color') ->visible(fn (Get $get) => $get('type') === 'color')
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'color') return;
$value = $get('value');
if ($value !== null && is_string($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -343,7 +417,13 @@ class PageForm
->displayFormat('d/m/Y') ->displayFormat('d/m/Y')
->live() ->live()
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'date') return;
$value = $get('value');
if ($value !== null && is_string($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -355,7 +435,13 @@ class PageForm
->seconds(false) ->seconds(false)
->live() ->live()
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'datetime') return;
$value = $get('value');
if ($value !== null && is_string($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
@@ -370,7 +456,13 @@ class PageForm
) )
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, callable $set) => $set('value', $state)) ->afterStateUpdated(fn ($state, callable $set) => $set('value', $state))
->afterStateHydrated(fn ($component, $state, Get $get) => $component->state($get('value'))) ->afterStateHydrated(function ($component, $state, Get $get) {
if ($get('type') !== 'array') return;
$value = $get('value');
if ($value !== null && is_array($value)) {
$component->state($value);
}
})
->dehydrated(false) ->dehydrated(false)
->columnSpanFull(), ->columnSpanFull(),
]) ])