german translations and some minor changes to the UI to make it prettier
This commit is contained in:
@@ -812,31 +812,61 @@ export default function AdminPage() {
|
||||
<div className="flex flex-col sm:flex-row gap-2">
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="w-full sm:w-auto px-4 py-3 sm:py-2 bg-red-600 text-white rounded hover:bg-red-700 text-sm sm:text-base font-medium"
|
||||
className="w-full sm:w-auto px-4 py-3 sm:py-2 bg-gradient-to-r from-red-600 to-pink-500 text-white rounded-xl shadow-lg flex items-center justify-center gap-2 text-sm sm:text-base font-semibold hover:from-red-700 hover:to-pink-600 transition-all focus:outline-none focus:ring-2 focus:ring-red-400"
|
||||
title="Logout"
|
||||
>
|
||||
Logout
|
||||
<svg className="h-5 w-5 sm:h-6 sm:w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
<span className="flex flex-col items-start">
|
||||
<span>Abmelden</span>
|
||||
<span className="text-xs font-normal text-red-100">Ausloggen</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowChangePassword(true)}
|
||||
className="w-full sm:w-auto px-4 py-3 sm:py-2 bg-blue-600 text-white rounded hover:bg-blue-700 text-sm sm:text-base font-medium"
|
||||
className="w-full sm:w-auto px-4 py-3 sm:py-2 bg-gradient-to-r from-blue-600 to-cyan-500 text-white rounded-xl shadow-lg flex items-center justify-center gap-2 text-sm sm:text-base font-semibold hover:from-blue-700 hover:to-cyan-600 transition-all focus:outline-none focus:ring-2 focus:ring-blue-400"
|
||||
title="Passwort ändern"
|
||||
>
|
||||
Passwort ändern
|
||||
<svg className="h-5 w-5 sm:h-6 sm:w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 11c1.104 0 2-.896 2-2s-.896-2-2-2-2 .896-2 2 .896 2 2 2zm6 2v5a2 2 0 01-2 2H8a2 2 0 01-2-2v-5m12 0V9a6 6 0 10-12 0v4m12 0H6" />
|
||||
</svg>
|
||||
<span className="flex flex-col items-start">
|
||||
<span>Passwort ändern</span>
|
||||
<span className="text-xs font-normal text-blue-100">Passwort ändern</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{/* Docker warning above export button */}
|
||||
{isDocker && (
|
||||
<div className="px-4 py-2 bg-yellow-200 text-yellow-900 rounded border border-yellow-400 font-semibold text-xs sm:text-sm text-center">
|
||||
<span className="font-bold">Warning:</span> Docker is in use. Exporting will export the entire <span className="font-mono">/app</span> root directory (including all files and folders in the container's root).
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col sm:flex-row items-center gap-2">
|
||||
<button
|
||||
onClick={handleExportTarball}
|
||||
className="w-full sm:w-auto px-4 py-3 sm:py-2 bg-green-600 text-white rounded hover:bg-green-700 text-sm sm:text-base font-medium whitespace-nowrap"
|
||||
className="w-full sm:w-auto px-4 py-3 sm:py-2 bg-gradient-to-r from-green-600 to-emerald-500 text-white rounded-xl shadow-lg flex items-center justify-center gap-2 text-sm sm:text-base font-semibold hover:from-green-700 hover:to-emerald-600 transition-all focus:outline-none focus:ring-2 focus:ring-green-400"
|
||||
title="Export Docker Posts"
|
||||
>
|
||||
Export Posts
|
||||
<svg className="h-5 w-5 sm:h-6 sm:w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<rect x="4" y="4" width="16" height="16" rx="3" stroke="currentColor" strokeWidth="2" fill="none" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M8 12h8M12 8v8" />
|
||||
</svg>
|
||||
<span className="flex flex-col items-start">
|
||||
<span>Exportieren</span>
|
||||
<span className="text-xs font-normal text-green-100">Alle exportieren</span>
|
||||
</span>
|
||||
</button>
|
||||
<a
|
||||
href="/admin/manage/rust-status"
|
||||
className="w-full sm:w-auto px-4 py-3 sm:py-2 bg-gradient-to-r from-teal-500 to-blue-500 text-white rounded-xl shadow-lg flex items-center justify-center gap-2 text-sm sm:text-base font-semibold hover:from-teal-600 hover:to-blue-600 transition-all focus:outline-none focus:ring-2 focus:ring-teal-400"
|
||||
title="View Rust Parser Dashboard"
|
||||
style={{ minWidth: '160px' }}
|
||||
>
|
||||
<svg className="h-5 w-5 sm:h-6 sm:w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="2" fill="none" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 16h-1v-4h-1m1-4h.01" />
|
||||
</svg>
|
||||
<span className="flex flex-col items-start">
|
||||
<span>Rust-Parser</span>
|
||||
<span className="text-xs font-normal text-teal-100">Statistiken</span>
|
||||
</span>
|
||||
</a>
|
||||
{rememberExportChoice && lastExportChoice && (
|
||||
<div className="flex items-center gap-1 text-xs text-gray-600 w-full sm:w-auto justify-center sm:justify-start">
|
||||
<span>💾 {lastExportChoice === 'docker' ? 'Docker' : 'Local'}</span>
|
||||
@@ -960,26 +990,7 @@ export default function AdminPage() {
|
||||
Current folder: <span className="font-mono">{currentPath.join('/') || 'root'}</span>
|
||||
</div>
|
||||
|
||||
{/* Create Folder Form */}
|
||||
<div className="bg-white rounded-lg shadow p-4 sm:p-6 mb-6 sm:mb-8">
|
||||
<h2 className="text-xl sm:text-2xl font-bold mb-4">Create New Folder</h2>
|
||||
<form onSubmit={handleCreateFolder} className="flex flex-col sm:flex-row gap-3 sm:gap-4">
|
||||
<input
|
||||
type="text"
|
||||
value={newFolderName}
|
||||
onChange={(e) => setNewFolderName(e.target.value)}
|
||||
placeholder="Folder name"
|
||||
className="flex-1 rounded-md border border-gray-300 px-3 py-2 text-base"
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-3 sm:py-2 bg-green-600 text-white rounded hover:bg-green-700 text-base font-medium"
|
||||
>
|
||||
Create Folder
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Drag and Drop Zone */}
|
||||
<div
|
||||
@@ -991,14 +1002,35 @@ export default function AdminPage() {
|
||||
onDrop={handleDrop}
|
||||
>
|
||||
<div className="text-gray-600">
|
||||
<p className="text-base sm:text-lg font-medium">Drag and drop Markdown files here</p>
|
||||
<p className="text-xs sm:text-sm">Files will be uploaded to: {currentPath.join('/') || 'root'}</p>
|
||||
<p className="text-base sm:text-lg font-medium">Ziehe Markdown-Dateien hierher</p>
|
||||
<p className="text-xs sm:text-sm">Dateien werden hochgeladen zu: {currentPath.join('/') || 'root'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Create Folder Form */}
|
||||
<div className="bg-white rounded-lg shadow p-4 sm:p-6 mb-6 sm:mb-8">
|
||||
<h2 className="text-xl sm:text-2xl font-bold mb-4">Create New Folder</h2>
|
||||
<form onSubmit={handleCreateFolder} className="flex flex-col sm:flex-row gap-3 sm:gap-4">
|
||||
<input
|
||||
type="text"
|
||||
value={newFolderName}
|
||||
onChange={(e) => setNewFolderName(e.target.value)}
|
||||
placeholder="Ordnername"
|
||||
className="flex-1 rounded-md border border-gray-300 px-3 py-2 text-base"
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-3 sm:py-2 bg-green-600 text-white rounded hover:bg-green-700 text-base font-medium"
|
||||
>
|
||||
Ordner erstellen
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{/* Create Post Form */}
|
||||
<div className="bg-white rounded-lg shadow p-4 sm:p-6 mb-6 sm:mb-8">
|
||||
<h2 className="text-xl sm:text-2xl font-bold mb-4">Create New Post</h2>
|
||||
<h2 className="text-xl sm:text-2xl font-bold mb-4">Erstelle neuen Beitrag</h2>
|
||||
<form onSubmit={editingPost ? handleEditPost : handleCreatePost} className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Title</label>
|
||||
@@ -1011,7 +1043,7 @@ export default function AdminPage() {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Date</label>
|
||||
<label className="block text-sm font-medium text-gray-700">Datum</label>
|
||||
<input
|
||||
type="date"
|
||||
value={newPost.date}
|
||||
@@ -1021,7 +1053,7 @@ export default function AdminPage() {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Tags (comma-separated)</label>
|
||||
<label className="block text-sm font-medium text-gray-700">Tags (komma-getrennt)</label>
|
||||
<input
|
||||
type="text"
|
||||
value={newPost.tags}
|
||||
@@ -1031,7 +1063,7 @@ export default function AdminPage() {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Summary</label>
|
||||
<label className="block text-sm font-medium text-gray-700">Zusammenfassung</label>
|
||||
<textarea
|
||||
value={newPost.summary}
|
||||
onChange={(e) => setNewPost({ ...newPost, summary: e.target.value })}
|
||||
@@ -1044,7 +1076,7 @@ export default function AdminPage() {
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<div className="w-full sm:w-1/2">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Content (Markdown)</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Inhalt (Markdown)</label>
|
||||
<textarea
|
||||
value={newPost.content}
|
||||
onChange={(e) => setNewPost({ ...newPost, content: e.target.value })}
|
||||
@@ -1055,7 +1087,7 @@ export default function AdminPage() {
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full sm:w-1/2">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Live Preview</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Vorschau</label>
|
||||
<div className="p-3 sm:p-4 border rounded bg-gray-50 overflow-auto" style={{ height: '240px' }}>
|
||||
<div className="prose prose-sm max-w-none" dangerouslySetInnerHTML={{ __html: previewHtml }} />
|
||||
</div>
|
||||
@@ -1066,14 +1098,14 @@ export default function AdminPage() {
|
||||
type="submit"
|
||||
className="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-blue-600 hover:bg-blue-700"
|
||||
>
|
||||
{editingPost ? 'Save Changes' : 'Create Post'}
|
||||
{editingPost ? 'Speichern' : 'Beitrag erstellen'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{/* Content List */}
|
||||
<div className="bg-white rounded-lg shadow p-4 sm:p-6">
|
||||
<h2 className="text-xl sm:text-2xl font-bold mb-4">Content</h2>
|
||||
<h2 className="text-xl sm:text-2xl font-bold mb-4">Inhalt:</h2>
|
||||
<div className="space-y-4">
|
||||
{/* Folders */}
|
||||
{currentNodes
|
||||
@@ -1200,7 +1232,7 @@ export default function AdminPage() {
|
||||
{showManageContent && (
|
||||
<div className="mt-4 bg-white p-4 sm:p-6 rounded-lg shadow text-center">
|
||||
<p className="text-gray-600 mb-2 text-sm sm:text-base">
|
||||
Delete posts and folders, manage your content structure
|
||||
Lösche Beiträge und Ordner, verwalte deine Inhaltsstruktur
|
||||
</p>
|
||||
{/* Folder navigation breadcrumbs */}
|
||||
<div className="flex flex-wrap justify-center gap-1 sm:gap-2 mb-4">
|
||||
@@ -1208,7 +1240,7 @@ export default function AdminPage() {
|
||||
onClick={() => setManagePath([])}
|
||||
className={`px-2 py-1 rounded text-sm sm:text-base ${managePath.length === 0 ? 'bg-blue-100 text-blue-800' : 'hover:bg-gray-200'}`}
|
||||
>
|
||||
Root
|
||||
/
|
||||
</button>
|
||||
{managePath.map((name, idx) => (
|
||||
<button
|
||||
@@ -1319,7 +1351,7 @@ export default function AdminPage() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<a href="/admin/manage" className="block mt-6 text-blue-600 hover:underline text-sm sm:text-base">Go to Content Manager</a>
|
||||
<a href="/admin/manage" className="block mt-6 text-blue-600 hover:underline text-sm sm:text-base">Zur Inhaltsverwaltung</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -1327,4 +1359,4 @@ export default function AdminPage() {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user