442 lines
20 KiB
PHP
442 lines
20 KiB
PHP
<?php
|
|
|
|
use App\Services\ProjectDocumentationContent;
|
|
use function Livewire\Volt\computed;
|
|
use function Livewire\Volt\state;
|
|
|
|
state(['showToc' => false]);
|
|
|
|
$content = computed(fn () => ProjectDocumentationContent::html());
|
|
$tableOfContents = computed(fn () => ProjectDocumentationContent::tableOfContents());
|
|
$fileInfo = computed(fn () => ProjectDocumentationContent::fileInfo());
|
|
|
|
?>
|
|
|
|
<div class="space-y-6 pb-12">
|
|
{{-- Sticky Header --}}
|
|
<div class="sticky top-0 z-10 bg-zinc-50 dark:bg-zinc-800 pb-4 border-b border-zinc-200 dark:border-zinc-700">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<flux:heading size="xl">{{ __('Projekt-Dokumentation') }}</flux:heading>
|
|
<flux:subheading>{{ __('Entwicklungsstand & Technische Übersicht') }}</flux:subheading>
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<flux:button
|
|
variant="ghost"
|
|
size="sm"
|
|
icon="list-bullet"
|
|
wire:click="$toggle('showToc')"
|
|
>
|
|
{{ __('Inhaltsverzeichnis') }}
|
|
</flux:button>
|
|
<flux:button
|
|
variant="ghost"
|
|
size="sm"
|
|
icon="arrow-down-tray"
|
|
href="{{ route('admin.documentation.download') }}"
|
|
>
|
|
{{ __('Download') }}
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- File Info Bar --}}
|
|
@if($this->fileInfo)
|
|
<div class="flex items-center gap-4 mt-3 text-xs text-zinc-600 dark:text-zinc-400">
|
|
<div class="flex items-center gap-1">
|
|
<flux:icon.document-text class="w-3 h-3" />
|
|
<span>{{ $this->fileInfo['size'] }}</span>
|
|
</div>
|
|
<div class="flex items-center gap-1">
|
|
<flux:icon.clock class="w-3 h-3" />
|
|
<span>{{ __('Aktualisiert:') }} {{ $this->fileInfo['modified'] }}</span>
|
|
</div>
|
|
<div class="flex items-center gap-1">
|
|
<flux:icon.bars-3 class="w-3 h-3" />
|
|
<span>{{ $this->fileInfo['lines'] }} {{ __('Zeilen') }}</span>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
{{-- Table of Contents Sidebar (Collapsible) --}}
|
|
@if($showToc)
|
|
<flux:card class="p-6 bg-gradient-to-br from-accent-50 to-blue-50 dark:from-accent-900/20 dark:to-blue-900/20 border-accent-200 dark:border-accent-800">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<flux:heading size="lg">{{ __('Inhaltsverzeichnis') }}</flux:heading>
|
|
<flux:button variant="ghost" size="sm" icon="x-mark" wire:click="$set('showToc', false)" />
|
|
</div>
|
|
<div class="space-y-2">
|
|
@foreach($this->tableOfContents as $item)
|
|
<a href="#{{ $item['slug'] }}"
|
|
class="block py-1.5 px-3 rounded-lg hover:bg-white dark:hover:bg-zinc-800 transition-colors
|
|
{{ $item['level'] === 2 ? 'font-semibold text-zinc-900 dark:text-zinc-100' : 'ml-4 text-sm text-zinc-700 dark:text-zinc-300' }}"
|
|
wire:click="$set('showToc', false)">
|
|
{{ $item['level'] === 3 ? '• ' : '' }}{{ $item['title'] }}
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
</flux:card>
|
|
@endif
|
|
|
|
{{-- Markdown Content with Enhanced Styling --}}
|
|
<div class="relative">
|
|
<flux:card class="p-6 lg:p-8 shadow-lg">
|
|
<style>
|
|
/* Force headings visibility and styling - reduced by 30% */
|
|
.prose h1 {
|
|
display: block !important;
|
|
font-size: 2.1rem !important;
|
|
font-weight: 700 !important;
|
|
line-height: 1.2 !important;
|
|
margin-top: 2.1rem !important;
|
|
margin-bottom: 1.4rem !important;
|
|
padding-bottom: 1rem !important;
|
|
border-bottom: 2px solid #e5e7eb !important;
|
|
background: linear-gradient(to right, #3b82f6, #2563eb) !important;
|
|
-webkit-background-clip: text !important;
|
|
-webkit-text-fill-color: transparent !important;
|
|
background-clip: text !important;
|
|
}
|
|
|
|
.prose h2 {
|
|
display: block !important;
|
|
font-size: 1.3125rem !important;
|
|
font-weight: 700 !important;
|
|
line-height: 1.3 !important;
|
|
margin-top: 2.1rem !important;
|
|
margin-bottom: 1rem !important;
|
|
padding-bottom: 0.5rem !important;
|
|
border-bottom: 1px solid #e5e7eb !important;
|
|
scroll-margin-top: 5rem !important;
|
|
}
|
|
|
|
.prose h3 {
|
|
display: block !important;
|
|
font-size: 1.05rem !important;
|
|
font-weight: 700 !important;
|
|
line-height: 1.4 !important;
|
|
margin-top: 1.4rem !important;
|
|
margin-bottom: 0.7rem !important;
|
|
scroll-margin-top: 5rem !important;
|
|
}
|
|
|
|
.prose h4 {
|
|
display: block !important;
|
|
font-size: 0.875rem !important;
|
|
font-weight: 600 !important;
|
|
line-height: 1.5 !important;
|
|
margin-top: 1rem !important;
|
|
margin-bottom: 0.5rem !important;
|
|
}
|
|
|
|
/* Dark mode headings */
|
|
.dark .prose h1 {
|
|
border-bottom-color: #374151 !important;
|
|
}
|
|
|
|
.dark .prose h2 {
|
|
border-bottom-color: #374151 !important;
|
|
color: #f9fafb !important;
|
|
}
|
|
|
|
.dark .prose h3 {
|
|
color: #e5e7eb !important;
|
|
}
|
|
|
|
.dark .prose h4 {
|
|
color: #d1d5db !important;
|
|
}
|
|
|
|
/* Force list indentation and visibility - reduced by 30% */
|
|
.prose ul {
|
|
list-style-type: disc !important;
|
|
margin-left: 1.75rem !important;
|
|
padding-left: 0.7rem !important;
|
|
margin-top: 0.7rem !important;
|
|
margin-bottom: 0.7rem !important;
|
|
}
|
|
|
|
.prose ol {
|
|
list-style-type: decimal !important;
|
|
margin-left: 1.75rem !important;
|
|
padding-left: 0.7rem !important;
|
|
margin-top: 0.7rem !important;
|
|
margin-bottom: 0.7rem !important;
|
|
}
|
|
|
|
.prose li {
|
|
display: list-item !important;
|
|
margin-bottom: 0.35rem !important;
|
|
padding-left: 0.35rem !important;
|
|
font-size: 0.95rem !important;
|
|
line-height: 1.5 !important;
|
|
}
|
|
|
|
.prose ul ul, .prose ol ol,
|
|
.prose ul ol, .prose ol ul {
|
|
margin-left: 1.4rem !important;
|
|
margin-top: 0.35rem !important;
|
|
margin-bottom: 0.35rem !important;
|
|
}
|
|
|
|
/* Paragraphs - reduced by 30% */
|
|
.prose p {
|
|
margin-top: 0.7rem !important;
|
|
margin-bottom: 0.7rem !important;
|
|
line-height: 1.6 !important;
|
|
font-size: 0.95rem !important;
|
|
}
|
|
|
|
/* Strong/Bold */
|
|
.prose strong {
|
|
font-weight: 700 !important;
|
|
color: #111827 !important;
|
|
font-size: 0.95rem !important;
|
|
}
|
|
|
|
.dark .prose strong {
|
|
color: #f9fafb !important;
|
|
}
|
|
|
|
/* Code - reduced by 30% */
|
|
.prose code {
|
|
background-color: #f3f4f6 !important;
|
|
padding: 0.175rem 0.35rem !important;
|
|
border-radius: 0.25rem !important;
|
|
font-size: 0.8rem !important;
|
|
font-weight: 600 !important;
|
|
}
|
|
|
|
.dark .prose code {
|
|
background-color: #1f2937 !important;
|
|
color: #60a5fa !important;
|
|
}
|
|
|
|
/* HR - reduced by 30% */
|
|
.prose hr {
|
|
margin-top: 2.1rem !important;
|
|
margin-bottom: 2.1rem !important;
|
|
border-color: #e5e7eb !important;
|
|
}
|
|
|
|
.dark .prose hr {
|
|
border-color: #374151 !important;
|
|
}
|
|
</style>
|
|
|
|
<div class="prose prose-zinc dark:prose-invert max-w-none
|
|
{{-- Headings --}}
|
|
prose-headings:font-bold prose-headings:tracking-tight
|
|
prose-h1:text-5xl prose-h1:mb-8 prose-h1:mt-12 prose-h1:pb-6
|
|
prose-h1:border-b-2 prose-h1:border-accent-300 dark:prose-h1:border-accent-700
|
|
prose-h1:text-transparent prose-h1:bg-clip-text prose-h1:bg-gradient-to-r prose-h1:from-accent-600 prose-h1:to-blue-600 dark:prose-h1:from-accent-400 dark:prose-h1:to-blue-400
|
|
|
|
prose-h2:text-3xl prose-h2:mb-6 prose-h2:mt-12 prose-h2:pb-3
|
|
prose-h2:border-b prose-h2:border-zinc-200 dark:prose-h2:border-zinc-700
|
|
prose-h2:text-zinc-900 dark:prose-h2:text-zinc-100
|
|
prose-h2:scroll-mt-20
|
|
|
|
prose-h3:text-2xl prose-h3:mb-4 prose-h3:mt-8
|
|
prose-h3:text-zinc-800 dark:prose-h3:text-zinc-200
|
|
prose-h3:scroll-mt-20
|
|
|
|
prose-h4:text-xl prose-h4:mb-3 prose-h4:mt-6
|
|
prose-h4:text-zinc-700 dark:prose-h4:text-zinc-300
|
|
|
|
{{-- Paragraphs & Text --}}
|
|
prose-p:mb-6 prose-p:leading-relaxed prose-p:text-zinc-700 dark:prose-p:text-zinc-300
|
|
|
|
{{-- Links --}}
|
|
prose-a:text-accent-600 dark:prose-a:text-accent-400
|
|
prose-a:font-medium prose-a:no-underline
|
|
prose-a:transition-all prose-a:duration-200
|
|
hover:prose-a:text-accent-700 dark:hover:prose-a:text-accent-300
|
|
hover:prose-a:underline hover:prose-a:decoration-2 hover:prose-a:underline-offset-4
|
|
|
|
{{-- Strong & Emphasis --}}
|
|
prose-strong:text-zinc-900 dark:prose-strong:text-zinc-100
|
|
prose-strong:font-bold
|
|
prose-em:text-zinc-800 dark:prose-em:text-zinc-200
|
|
|
|
{{-- Code --}}
|
|
prose-code:bg-accent-100 dark:prose-code:bg-accent-900/30
|
|
prose-code:text-accent-900 dark:prose-code:text-accent-100
|
|
prose-code:px-2 prose-code:py-1 prose-code:rounded-md
|
|
prose-code:text-sm prose-code:font-mono prose-code:font-semibold
|
|
prose-code:before:content-none prose-code:after:content-none
|
|
prose-code:border prose-code:border-accent-200 dark:prose-code:border-accent-800
|
|
|
|
{{-- Code Blocks --}}
|
|
prose-pre:bg-gradient-to-br prose-pre:from-zinc-900 prose-pre:to-zinc-800
|
|
dark:prose-pre:from-zinc-950 dark:prose-pre:to-zinc-900
|
|
prose-pre:p-6 prose-pre:rounded-xl prose-pre:overflow-x-auto
|
|
prose-pre:shadow-xl prose-pre:border prose-pre:border-zinc-700 dark:prose-pre:border-zinc-800
|
|
prose-pre:my-8
|
|
|
|
{{-- Lists --}}
|
|
prose-ul:list-disc prose-ul:ml-8 prose-ul:pl-6 prose-ul:mb-6 prose-ul:space-y-2
|
|
prose-ol:list-decimal prose-ol:ml-8 prose-ol:pl-6 prose-ol:mb-6 prose-ol:space-y-2
|
|
prose-li:text-zinc-700 dark:prose-li:text-zinc-300
|
|
prose-li:leading-relaxed prose-li:pl-3
|
|
prose-li:marker:text-accent-500 dark:prose-li:marker:text-accent-400
|
|
prose-li:marker:font-bold
|
|
|
|
{{-- Nested Lists --}}
|
|
prose-ul prose-ul:ml-8 prose-ul prose-ul:space-y-1
|
|
prose-ol prose-ol:ml-8 prose-ol prose-ol:space-y-1
|
|
|
|
{{-- Blockquotes --}}
|
|
prose-blockquote:border-l-4 prose-blockquote:border-accent-500 dark:prose-blockquote:border-accent-400
|
|
prose-blockquote:bg-accent-50 dark:prose-blockquote:bg-accent-900/10
|
|
prose-blockquote:pl-6 prose-blockquote:pr-4 prose-blockquote:py-4
|
|
prose-blockquote:italic prose-blockquote:text-zinc-700 dark:prose-blockquote:text-zinc-300
|
|
prose-blockquote:rounded-r-lg prose-blockquote:my-8
|
|
prose-blockquote:shadow-sm
|
|
|
|
{{-- HR --}}
|
|
prose-hr:border-zinc-300 dark:prose-hr:border-zinc-600
|
|
prose-hr:my-12 prose-hr:border-t-2
|
|
|
|
{{-- Tables --}}
|
|
prose-table:border-collapse prose-table:w-full
|
|
prose-table:shadow-lg prose-table:rounded-lg prose-table:overflow-hidden
|
|
prose-table:my-8
|
|
|
|
prose-thead:bg-gradient-to-r prose-thead:from-accent-100 prose-thead:to-blue-100
|
|
dark:prose-thead:from-accent-900/40 dark:prose-thead:to-blue-900/40
|
|
|
|
prose-th:p-4 prose-th:text-left prose-th:font-bold
|
|
prose-th:text-zinc-900 dark:prose-th:text-zinc-100
|
|
prose-th:border-b-2 prose-th:border-accent-300 dark:prose-th:border-accent-700
|
|
|
|
prose-td:p-4 prose-td:border-b prose-td:border-zinc-200 dark:prose-td:border-zinc-700
|
|
prose-td:text-zinc-700 dark:prose-td:text-zinc-300
|
|
|
|
prose-tr:transition-colors
|
|
hover:prose-tr:bg-zinc-50 dark:hover:prose-tr:bg-zinc-800/50
|
|
|
|
{{-- Images --}}
|
|
prose-img:rounded-xl prose-img:shadow-2xl prose-img:my-8
|
|
prose-img:border prose-img:border-zinc-200 dark:prose-img:border-zinc-700
|
|
">
|
|
{!! $this->content !!}
|
|
</div>
|
|
|
|
{{-- Scroll to top button --}}
|
|
<div class="flex justify-center mt-12 pt-8 border-t border-zinc-200 dark:border-zinc-700">
|
|
<flux:button
|
|
variant="ghost"
|
|
icon="arrow-up"
|
|
onclick="window.scrollTo({top: 0, behavior: 'smooth'})"
|
|
>
|
|
{{ __('Zurück nach oben') }}
|
|
</flux:button>
|
|
</div>
|
|
</flux:card>
|
|
</div>
|
|
|
|
{{-- Quick Reference Grid --}}
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<flux:card class="p-6 bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 border-blue-200 dark:border-blue-800">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-blue-500 rounded-lg">
|
|
<flux:icon.cube class="w-5 h-5 text-white" />
|
|
</div>
|
|
<flux:heading size="sm" class="text-blue-900 dark:text-blue-100">{{ __('Module') }}</flux:heading>
|
|
</div>
|
|
<ul class="space-y-2 text-sm text-blue-800 dark:text-blue-200">
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-blue-600 dark:text-blue-400" />
|
|
Multi-Domain-System
|
|
</li>
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-blue-600 dark:text-blue-400" />
|
|
Benutzer-Management
|
|
</li>
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-blue-600 dark:text-blue-400" />
|
|
Partner-Verwaltung
|
|
</li>
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-blue-600 dark:text-blue-400" />
|
|
Hub-System
|
|
</li>
|
|
</ul>
|
|
</flux:card>
|
|
|
|
<flux:card class="p-6 bg-gradient-to-br from-purple-50 to-pink-50 dark:from-purple-900/20 dark:to-pink-900/20 border-purple-200 dark:border-purple-800">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-purple-500 rounded-lg">
|
|
<flux:icon.code-bracket class="w-5 h-5 text-white" />
|
|
</div>
|
|
<flux:heading size="sm" class="text-purple-900 dark:text-purple-100">{{ __('Technologien') }}</flux:heading>
|
|
</div>
|
|
<ul class="space-y-2 text-sm text-purple-800 dark:text-purple-200">
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-purple-600 dark:text-purple-400" />
|
|
Laravel 12
|
|
</li>
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-purple-600 dark:text-purple-400" />
|
|
Livewire 3 + Volt
|
|
</li>
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-purple-600 dark:text-purple-400" />
|
|
Flux UI Pro
|
|
</li>
|
|
<li class="flex items-center gap-2">
|
|
<flux:icon.check class="w-4 h-4 text-purple-600 dark:text-purple-400" />
|
|
Spatie Permissions
|
|
</li>
|
|
</ul>
|
|
</flux:card>
|
|
|
|
<flux:card class="p-6 bg-gradient-to-br from-green-50 to-emerald-50 dark:from-green-900/20 dark:to-emerald-900/20 border-green-200 dark:border-green-800">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<div class="p-2 bg-green-500 rounded-lg">
|
|
<flux:icon.chart-bar class="w-5 h-5 text-white" />
|
|
</div>
|
|
<flux:heading size="sm" class="text-green-900 dark:text-green-100">{{ __('Status-Legende') }}</flux:heading>
|
|
</div>
|
|
<div class="space-y-3 text-sm">
|
|
<div class="flex items-center gap-2">
|
|
<flux:badge color="green" size="sm">✓</flux:badge>
|
|
<span class="text-green-800 dark:text-green-200">{{ __('Vollständig implementiert') }}</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<flux:badge color="yellow" size="sm">●</flux:badge>
|
|
<span class="text-green-800 dark:text-green-200">{{ __('In Entwicklung') }}</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<flux:badge color="zinc" size="sm">○</flux:badge>
|
|
<span class="text-green-800 dark:text-green-200">{{ __('Geplant') }}</span>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
</div>
|
|
|
|
{{-- Footer Metadata --}}
|
|
<flux:card class="p-6 bg-gradient-to-r from-zinc-50 to-zinc-100 dark:from-zinc-900 dark:to-zinc-800 border-0">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-6 text-sm text-zinc-600 dark:text-zinc-400">
|
|
<div class="flex items-center gap-2">
|
|
<flux:icon.document-text class="w-4 h-4" />
|
|
<span class="font-mono">entwicklung.md</span>
|
|
</div>
|
|
@if($this->fileInfo)
|
|
<div class="flex items-center gap-2">
|
|
<flux:icon.clock class="w-4 h-4" />
|
|
<span>{{ __('Zuletzt aktualisiert:') }} {{ $this->fileInfo['modified'] }}</span>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
<div>
|
|
<flux:badge color="accent" size="sm">
|
|
{{ __('Live-Dokumentation') }}
|
|
</flux:badge>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
</div>
|
|
|