Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
561
src/Application/Design/Views/component-detail.view.php
Normal file
561
src/Application/Design/Views/component-detail.view.php
Normal file
@@ -0,0 +1,561 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{meta.title}}</title>
|
||||
<link rel="stylesheet" href="/assets/css/admin.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-css.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-markup.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css">
|
||||
<style>
|
||||
.component-detail-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
min-height: 100vh;
|
||||
background-color: #f8fafc;
|
||||
}
|
||||
|
||||
.component-sidebar {
|
||||
background: white;
|
||||
border-right: 1px solid #e2e8f0;
|
||||
padding: 1.5rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.component-main {
|
||||
padding: 2rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.component-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.back-link {
|
||||
color: #6b7280;
|
||||
text-decoration: none;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.back-link:hover {
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.component-meta {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
padding: 1rem;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
font-size: 0.75rem;
|
||||
color: #6b7280;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.category-badge {
|
||||
background: #dbeafe;
|
||||
color: #1d4ed8;
|
||||
padding: 0.125rem 0.375rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.pattern-badge {
|
||||
background: #d1fae5;
|
||||
color: #065f46;
|
||||
padding: 0.125rem 0.375rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.component-preview-section {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e2e8f0;
|
||||
margin-bottom: 2rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
padding: 1rem 1.5rem;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
background: #f9fafb;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.preview-area {
|
||||
padding: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f9fafb;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.component-states {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 2rem;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.state-demo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.state-label {
|
||||
font-size: 0.75rem;
|
||||
color: #6b7280;
|
||||
margin-bottom: 1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.code-section {
|
||||
background: #1f2937;
|
||||
color: #e5e7eb;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.code-section pre {
|
||||
margin: 0;
|
||||
padding: 1.5rem;
|
||||
background: transparent;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.code-tabs {
|
||||
display: flex;
|
||||
background: #374151;
|
||||
border-bottom: 1px solid #4b5563;
|
||||
}
|
||||
|
||||
.code-tab {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #9ca3af;
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.code-tab.active {
|
||||
background: #1f2937;
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
||||
.code-tab:hover {
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
||||
.code-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.code-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.variants-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.variant-card {
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.variant-preview {
|
||||
padding: 2rem;
|
||||
background: #f9fafb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.variant-info {
|
||||
padding: 1rem;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.variant-name {
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.variant-selector {
|
||||
font-family: 'Monaco', 'Consolas', monospace;
|
||||
font-size: 0.75rem;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.sidebar-components {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar-component {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.sidebar-component-link {
|
||||
display: block;
|
||||
padding: 0.5rem 0.75rem;
|
||||
color: #6b7280;
|
||||
text-decoration: none;
|
||||
border-radius: 6px;
|
||||
font-size: 0.875rem;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.sidebar-component-link:hover,
|
||||
.sidebar-component-link.active {
|
||||
background: #f3f4f6;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
/* Component-specific styling for previews */
|
||||
.preview-area .btn {
|
||||
background: #3b82f6;
|
||||
color: white;
|
||||
padding: 0.5rem 1rem;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.preview-area .btn:hover {
|
||||
background: #2563eb;
|
||||
}
|
||||
|
||||
.preview-area .btn:focus {
|
||||
outline: 2px solid #3b82f6;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.preview-area .btn:active {
|
||||
background: #1d4ed8;
|
||||
}
|
||||
|
||||
.preview-area .btn:disabled {
|
||||
background: #9ca3af;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.preview-area .btn-secondary {
|
||||
background: #6b7280;
|
||||
}
|
||||
|
||||
.preview-area .btn-secondary:hover {
|
||||
background: #4b5563;
|
||||
}
|
||||
|
||||
.preview-area .btn-success {
|
||||
background: #10b981;
|
||||
}
|
||||
|
||||
.preview-area .btn-success:hover {
|
||||
background: #059669;
|
||||
}
|
||||
|
||||
.preview-area .btn-danger {
|
||||
background: #ef4444;
|
||||
}
|
||||
|
||||
.preview-area .btn-danger:hover {
|
||||
background: #dc2626;
|
||||
}
|
||||
|
||||
.preview-area .btn-warning {
|
||||
background: #f59e0b;
|
||||
}
|
||||
|
||||
.preview-area .btn-warning:hover {
|
||||
background: #d97706;
|
||||
}
|
||||
|
||||
.preview-area .card {
|
||||
background: white;
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e2e8f0;
|
||||
min-width: 250px;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.preview-area .card h3 {
|
||||
margin: 0 0 0.5rem 0;
|
||||
color: #1f2937;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.preview-area .card p {
|
||||
margin: 0;
|
||||
color: #6b7280;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.preview-area .alert {
|
||||
padding: 1rem;
|
||||
border-radius: 6px;
|
||||
min-width: 300px;
|
||||
font-size: 0.875rem;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.preview-area .alert-success {
|
||||
background: #dcfce7;
|
||||
color: #166534;
|
||||
border-color: #bbf7d0;
|
||||
}
|
||||
|
||||
.preview-area .alert-error {
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
border-color: #fecaca;
|
||||
}
|
||||
|
||||
.preview-area .alert-warning {
|
||||
background: #fef3c7;
|
||||
color: #d97706;
|
||||
border-color: #fed7aa;
|
||||
}
|
||||
|
||||
.preview-area .alert-info {
|
||||
background: #dbeafe;
|
||||
color: #1d4ed8;
|
||||
border-color: #bfdbfe;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="component-detail-layout">
|
||||
<!-- Sidebar -->
|
||||
<aside class="component-sidebar">
|
||||
<div class="mb-4">
|
||||
<a href="/design-system/components" class="back-link">← Component Library</a>
|
||||
<h2 class="text-lg font-semibold text-gray-900 mt-2">All Components</h2>
|
||||
</div>
|
||||
|
||||
<ul class="sidebar-components">
|
||||
<?php foreach ($allComponents as $comp): ?>
|
||||
<li class="sidebar-component">
|
||||
<a href="/design-system/components/<?php echo htmlspecialchars($comp->name); ?>"
|
||||
class="sidebar-component-link <?php echo $comp->name === $component->name ? 'active' : ''; ?>">
|
||||
<?php echo htmlspecialchars($comp->getDisplayName()); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="component-main">
|
||||
<!-- Header -->
|
||||
<div class="component-header">
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-gray-900">{{component.getDisplayName()}}</h1>
|
||||
<p class="text-gray-600 mt-1">Interactive component with live preview and code examples</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Component Meta -->
|
||||
<div class="component-meta">
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Category</div>
|
||||
<div class="meta-value">
|
||||
<span class="category-badge">{{component.category.value}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Pattern</div>
|
||||
<div class="meta-value">
|
||||
<span class="pattern-badge">{{component.pattern.value}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">State</div>
|
||||
<div class="meta-value">{{component.state.value}}</div>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Selector</div>
|
||||
<div class="meta-value" style="font-family: Monaco, Consolas, monospace; font-size: 0.75rem;">{{component.selector}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Live Preview -->
|
||||
<div class="component-preview-section">
|
||||
<div class="section-header">
|
||||
🎨 Live Preview
|
||||
</div>
|
||||
<div class="preview-area">
|
||||
{{{component.getPreviewHtml()}}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Component States -->
|
||||
<div class="component-preview-section">
|
||||
<div class="section-header">
|
||||
🔄 Component States
|
||||
</div>
|
||||
<div class="component-states">
|
||||
<div class="state-demo">
|
||||
<div class="state-label">Default</div>
|
||||
<div class="preview-area" style="padding: 2rem; min-height: auto;">
|
||||
{{{component.getPreviewHtml()}}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="state-demo">
|
||||
<div class="state-label">Hover</div>
|
||||
<div class="preview-area" style="padding: 2rem; min-height: auto;">
|
||||
<div style="opacity: 0.8; transform: translateY(-1px);">
|
||||
{{{component.getPreviewHtml()}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="state-demo">
|
||||
<div class="state-label">Focus</div>
|
||||
<div class="preview-area" style="padding: 2rem; min-height: auto;">
|
||||
<div style="box-shadow: 0 0 0 2px #3b82f6; border-radius: 6px;">
|
||||
{{{component.getPreviewHtml()}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="state-demo">
|
||||
<div class="state-label">Active</div>
|
||||
<div class="preview-area" style="padding: 2rem; min-height: auto;">
|
||||
<div style="transform: scale(0.98);">
|
||||
{{{component.getPreviewHtml()}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Code Examples -->
|
||||
<div class="component-preview-section">
|
||||
<div class="section-header">
|
||||
💻 Code Examples
|
||||
</div>
|
||||
<div class="code-tabs">
|
||||
<button class="code-tab active" data-tab="html">HTML</button>
|
||||
<button class="code-tab" data-tab="css">CSS</button>
|
||||
</div>
|
||||
<div class="code-section">
|
||||
<div class="code-content active" id="html-content">
|
||||
<pre><code class="language-html"><?php echo htmlspecialchars($component->getPreviewHtml()); ?></code></pre>
|
||||
</div>
|
||||
<div class="code-content" id="css-content">
|
||||
<pre><code class="language-css"><?php echo htmlspecialchars($component->selector . ' {' . "\n" . $component->cssRules . "\n" . '}'); ?></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Variants -->
|
||||
<?php if (!empty($variants) && count($variants) > 1): ?>
|
||||
<div class="component-preview-section">
|
||||
<div class="section-header">
|
||||
🧩 Component Variants ({{ count($variants) }})
|
||||
</div>
|
||||
<div class="variants-grid">
|
||||
<?php foreach ($variants as $variant): ?>
|
||||
<div class="variant-card">
|
||||
<div class="variant-preview">
|
||||
{{{$variant->getPreviewHtml()}}}
|
||||
</div>
|
||||
<div class="variant-info">
|
||||
<div class="variant-name"><?php echo htmlspecialchars($variant->getDisplayName()); ?></div>
|
||||
<div class="variant-selector"><?php echo htmlspecialchars($variant->selector); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Usage Guidelines -->
|
||||
<div class="component-preview-section">
|
||||
<div class="section-header">
|
||||
📖 Usage Guidelines
|
||||
</div>
|
||||
<div style="padding: 1.5rem;">
|
||||
<h3 style="margin: 0 0 1rem 0; color: #374151; font-size: 1rem;">When to use this component</h3>
|
||||
<p style="color: #6b7280; margin: 0 0 1rem 0; line-height: 1.6;">
|
||||
This <?php echo htmlspecialchars($component->category->value); ?> component follows the <?php echo htmlspecialchars($component->pattern->value); ?> pattern
|
||||
and is suitable for <?php echo htmlspecialchars($component->category->value); ?>-related user interface elements.
|
||||
</p>
|
||||
|
||||
<h3 style="margin: 1.5rem 0 1rem 0; color: #374151; font-size: 1rem;">Implementation Notes</h3>
|
||||
<ul style="color: #6b7280; margin: 0; padding-left: 1.5rem; line-height: 1.6;">
|
||||
<li>Component selector: <code style="background: #f3f4f6; padding: 0.125rem 0.25rem; border-radius: 3px;">{{component.selector}}</code></li>
|
||||
<li>Category: {{component.category.value}}</li>
|
||||
<li>Pattern: {{component.pattern.value}}</li>
|
||||
<li>Located in: <code style="background: #f3f4f6; padding: 0.125rem 0.25rem; border-radius: 3px;">{{component.filePath}}</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Code tab switching
|
||||
document.querySelectorAll('.code-tab').forEach(tab => {
|
||||
tab.addEventListener('click', function() {
|
||||
// Remove active from all tabs and contents
|
||||
document.querySelectorAll('.code-tab').forEach(t => t.classList.remove('active'));
|
||||
document.querySelectorAll('.code-content').forEach(c => c.classList.remove('active'));
|
||||
|
||||
// Add active to clicked tab
|
||||
this.classList.add('active');
|
||||
|
||||
// Show corresponding content
|
||||
const tabId = this.dataset.tab + '-content';
|
||||
document.getElementById(tabId).classList.add('active');
|
||||
|
||||
// Re-highlight code
|
||||
Prism.highlightAll();
|
||||
});
|
||||
});
|
||||
|
||||
// Initialize syntax highlighting
|
||||
Prism.highlightAll();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user