feat: WordPress tarzı rich editor (TipTap + slash menu + MediaPicker)
WordPress Gutenberg + Notion karışımı blok editor. 4 admin formunda markdown textarea yerine gerçek WYSIWYG editor. RichEditor component (components/admin/rich-editor.tsx): - TipTap v3 (@tiptap/react + starter-kit + link + image + placeholder + underline) - Üst toolbar (her zaman görünür): - B / I / U (bold, italic, underline) - H1 / H2 / H3 - Bullet list / Ordered list / Quote / Code block - Link (URL prompt) - Görsel ekle (MediaPicker modal) - Undo / Redo - Slash menu: '/' yazınca blok seçim menüsü açılır - Notion tarzı keyboard navigation (↓↑ Enter Esc) - 8 blok tipi: H1/H2/H3/ul/ol/quote/code/hr - Image picker modal (toolbar görsel butonundan) - Mevcut MediaPicker'ı kullanır - 'Yeni görsel yükle' (progress bar ile) + 'Kütüphaneden seç' grid - HTML çıktı (hidden input ile form'a) - Mevcut content alanlarıyla backward compat Formlarda değişiklik (4 dosya): - app/admin/(protected)/blog/form.tsx → content - app/admin/(protected)/hizmetler/form.tsx → content - app/admin/(protected)/projeler/form.tsx → content - app/admin/(protected)/sektorler/form.tsx → content Public render (lib/content-render.ts): - renderContent() yardımcısı: - İçerik '<' ile başlıyorsa → HTML (direkt döner) - Aksi halde → markdown (marked.parse) - 4 detay sayfası bu helper'ı kullanıyor (blog/[slug], projeler/[slug], hizmetler/[slug], sektor/[slug]) - Eski markdown içerikler hala çalışıyor, yeni içerikler HTML olarak gelir 37 route, build temiz.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import { marked } from "marked";
|
||||
|
||||
/**
|
||||
* Akıllı içerik render — RichEditor HTML üretir, eski içerikler markdown olabilir.
|
||||
* - HTML işareti (`<p>`, `<h1>` vs ile başlıyor) varsa direkt döner
|
||||
* - Aksi halde markdown olarak parse eder
|
||||
*/
|
||||
export function renderContent(content?: string | null): string {
|
||||
if (!content) return "";
|
||||
const trimmed = content.trim();
|
||||
if (!trimmed) return "";
|
||||
// HTML: ilk karakter '<' ise ve içinde HTML tag varsa
|
||||
if (trimmed.startsWith("<") && /<\w+[^>]*>/.test(trimmed)) {
|
||||
return trimmed;
|
||||
}
|
||||
return marked.parse(trimmed, { async: false }) as string;
|
||||
}
|
||||
Reference in New Issue
Block a user