This commit is contained in:
2025-06-19 13:40:31 +02:00
parent 24d03302b6
commit 60b66ef57c
9 changed files with 138 additions and 28 deletions

View File

@@ -3,6 +3,8 @@
import { useState, useEffect, useCallback, useRef } from 'react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { marked } from 'marked';
import hljs from 'highlight.js';
interface Post {
slug: string;
@@ -67,6 +69,7 @@ export default function AdminPage() {
const [changePwNew, setChangePwNew] = useState('');
const [changePwConfirm, setChangePwConfirm] = useState('');
const [changePwFeedback, setChangePwFeedback] = useState<string | null>(null);
const [previewHtml, setPreviewHtml] = useState('');
const router = useRouter();
const usernameRef = useRef<HTMLInputElement>(null);
const passwordRef = useRef<HTMLInputElement>(null);
@@ -85,6 +88,20 @@ export default function AdminPage() {
useEffect(() => {
localStorage.setItem('pinnedPosts', JSON.stringify(pinned));
}, [pinned]);
useEffect(() => {
marked.setOptions({
gfm: true,
breaks: true,
highlight: function(code: string, lang: string) {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(code, { language: lang }).value;
} else {
return hljs.highlightAuto(code).value;
}
}
} as any);
setPreviewHtml(marked.parse(newPost.content || '') as string);
}, [newPost.content]);
const loadContent = async () => {
try {
@@ -659,13 +676,21 @@ export default function AdminPage() {
</div>
<div>
<label className="block text-sm font-medium text-gray-700">Content (Markdown)</label>
<textarea
value={newPost.content}
onChange={(e) => setNewPost({ ...newPost, content: e.target.value })}
className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 font-mono"
rows={10}
required
/>
<div className="flex flex-col md:flex-row gap-4 mt-1">
{/* Markdown Editor */}
<textarea
value={newPost.content}
onChange={(e) => setNewPost({ ...newPost, content: e.target.value })}
className="w-full md:w-1/2 rounded-md border border-gray-300 px-3 py-2 font-mono min-h-[200px] md:min-h-[300px] resize-y"
rows={10}
required
/>
{/* Live Markdown Preview */}
<div className="w-full md:w-1/2 p-4 border rounded bg-gray-50 overflow-auto min-h-[200px] md:min-h-[300px]">
<div className="text-xs text-gray-500 mb-2">Live Preview</div>
<div className="prose prose-sm max-w-none" dangerouslySetInnerHTML={{ __html: previewHtml }} />
</div>
</div>
</div>
<button
type="submit"