Backup #998

ID998
Dateipfad/var/www/dev.campus.systemische-tools.de/src/View/content/show.php
Version26
Typ modified
Größe16.7 KB
Hash42fa2afcfc8e2084819352461f993a55774322fc78a8cab60687609d0b40968a
Datum2025-12-24 01:21:26
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php
ob_start();
$orderModel = $order['model'] ?? 'claude-sonnet-4-20250514';
$orderCollections = json_decode($order['collections'] ?? '["documents"]', true) ?: ['documents'];
$orderContextLimit = (int) ($order['context_limit'] ?? 5);
$isGenerating = ($order['generation_status'] ?? 'idle') === 'generating';
$orderId = $order['id'];
?>

<nav class="breadcrumb">
    <a href="/content">Content Studio</a> &raquo; Auftrag #<?= $order['id'] ?>
</nav>

<h1><?= htmlspecialchars($order['title']) ?></h1>

<div class="info-grid">
    <div class="info-card">
        <h3>Auftrag</h3>
        <dl class="info-list">
            <dt>ID</dt><dd><?= $order['id'] ?></dd>
            <dt>Status</dt><dd><span class="badge badge--<?= $order['status'] ?>"><?= $order['status'] ?></span></dd>
            <dt>Erstellt</dt><dd><?= $order['created_at'] ?></dd>
        </dl>
    </div>
    <div class="info-card">
        <h3>KI-Einstellungen</h3>
        <dl class="info-list">
            <dt>Modell</dt><dd><?= htmlspecialchars($models[$orderModel] ?? $orderModel) ?></dd>
            <dt>Collections</dt><dd><?= htmlspecialchars(implode(', ', $orderCollections)) ?></dd>
            <dt>Quellen</dt><dd><?= $orderContextLimit ?></dd>
        </dl>
    </div>
    <div class="info-card">
        <h3>Content-Config</h3>
        <dl class="info-list">
            <dt>Profil</dt><dd><?= htmlspecialchars($order['profile_name'] ?? '-') ?></dd>
            <dt>Contract</dt><dd><?= htmlspecialchars($order['contract_name'] ?? '-') ?></dd>
            <dt>Struktur</dt><dd><?= htmlspecialchars($order['structure_name'] ?? '-') ?></dd>
        </dl>
    </div>
</div>

<h2>Briefing</h2>
<div class="briefing-box"><?= nl2br(htmlspecialchars($order['briefing'])) ?></div>

<h2>Aktionen</h2>
<div class="action-cards">
    <!-- Basis-Aktionen -->
    <div class="action-card">
        <div class="action-card__header">Auftrag</div>
        <div class="action-card__body">
            <a href="/content/<?= $order['id'] ?>/edit" class="btn btn--full">Bearbeiten</a>
        </div>
    </div>

    <?php if (!$latestVersion): ?>
    <!-- Content Generieren -->
    <div class="action-card action-card--primary">
        <div class="action-card__header">Content generieren</div>
        <div class="action-card__desc">Erstellt Content basierend auf Briefing und RAG-Quellen</div>
        <form method="POST" action="/content/<?= $order['id'] ?>/generate" class="action-card__body generate-form" id="generate-form"
              hx-post="/content/<?= $order['id'] ?>/generate"
              hx-target="#content-result"
              hx-swap="innerHTML"
              hx-disabled-elt="find button">
            <?= $csrfField ?>
            <div class="form-row">
                <label class="form-label">KI-Modell</label>
                <select name="model" class="form-select" <?= $isGenerating ? 'disabled' : '' ?>>
                    <?php foreach ($models ?? [] as $modelId => $modelName): ?>
                    <option value="<?= $modelId ?>" <?= $modelId === $orderModel ? 'selected' : '' ?>><?= htmlspecialchars($modelName) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="form-row">
                <label class="form-label">Wissens-Quelle</label>
                <?php
                $collections = $availableCollections ?? [];
                $selected = $orderCollections;
                $name = 'collection';
                $variant = 'block';
                $multiple = false;
                include __DIR__ . '/../partials/form/collections-select.php';
                ?>
            </div>
            <div class="form-row">
                <label class="form-label">Kontext-Limit</label>
                <select name="context_limit" class="form-select" <?= $isGenerating ? 'disabled' : '' ?>>
                    <option value="3" <?= $orderContextLimit === 3 ? 'selected' : '' ?>>3 Quellen</option>
                    <option value="5" <?= $orderContextLimit === 5 ? 'selected' : '' ?>>5 Quellen</option>
                    <option value="10" <?= $orderContextLimit === 10 ? 'selected' : '' ?>>10 Quellen</option>
                    <option value="15" <?= $orderContextLimit === 15 ? 'selected' : '' ?>>15 Quellen</option>
                </select>
            </div>
            <button type="submit" class="btn btn--primary btn--full generate-btn <?= $isGenerating ? 'is-loading' : '' ?>" <?= $isGenerating ? 'disabled' : '' ?>>
                <span class="btn-text">Generieren</span>
                <span class="btn-loading"><span></span><span></span><span></span></span>
            </button>
        </form>
    </div>
    <?php endif; ?>

    <?php if ($latestVersion): ?>
    <!-- Kritik-Runde -->
    <div class="action-card">
        <div class="action-card__header">Kritik-Runde</div>
        <div class="action-card__desc">
            Alle aktiven Kritiker pruefen den Content:
            <a href="/critics" class="action-link">Faktenpruefer, Stilist, Strukturanalyst</a>
        </div>
        <form method="POST" action="/content/<?= $order['id'] ?>/critique" class="action-card__body critique-form"
              hx-post="/content/<?= $order['id'] ?>/critique"
              hx-target="#critique-result"
              hx-swap="innerHTML"
              hx-disabled-elt="find button">
            <?= $csrfField ?>
            <div class="form-row">
                <label class="form-label">KI-Modell fuer Kritik</label>
                <select name="model" class="form-select">
                    <?php foreach ($models ?? [] as $modelId => $modelName): ?>
                    <option value="<?= $modelId ?>" <?= $modelId === $orderModel ? 'selected' : '' ?>><?= htmlspecialchars($modelName) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <button type="submit" class="btn btn--light btn--full critique-btn">
                <span class="btn-text">Kritik starten</span>
                <span class="btn-loading"><span></span><span></span><span></span></span>
            </button>
        </form>
    </div>

    <!-- Revision -->
    <div class="action-card">
        <div class="action-card__header">Revision erstellen</div>
        <div class="action-card__desc">Ueberarbeitet Content basierend auf dem Kritik-Feedback</div>
        <form method="POST" action="/content/<?= $order['id'] ?>/revise" class="action-card__body revise-form"
              hx-post="/content/<?= $order['id'] ?>/revise"
              hx-target="#content-result"
              hx-swap="innerHTML"
              hx-disabled-elt="find button">
            <?= $csrfField ?>
            <div class="form-row">
                <label class="form-label">KI-Modell fuer Revision</label>
                <select name="model" class="form-select">
                    <?php foreach ($models ?? [] as $modelId => $modelName): ?>
                    <option value="<?= $modelId ?>" <?= $modelId === $orderModel ? 'selected' : '' ?>><?= htmlspecialchars($modelName) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <button type="submit" class="btn btn--light btn--full revise-btn">
                <span class="btn-text">Revision erstellen</span>
                <span class="btn-loading"><span></span><span></span><span></span></span>
            </button>
        </form>
    </div>

    <!-- Freigabe -->
    <?php if (in_array($order['status'], ['validate', 'critique', 'revision'])): ?>
    <div class="action-card">
        <div class="action-card__header">Freigabe</div>
        <div class="action-card__desc">Content genehmigen oder zurueck zu Entwurf</div>
        <div class="action-card__body action-card__buttons">
            <button class="btn btn--success btn--full" hx-post="/content/<?= $order['id'] ?>/approve" hx-swap="none" hx-on::after-request="location.reload()" hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'>Genehmigen</button>
            <button class="btn btn--danger btn--full" hx-post="/content/<?= $order['id'] ?>/decline" hx-swap="none" hx-on::after-request="location.reload()" hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'>Ablehnen</button>
        </div>
    </div>
    <?php endif; ?>
    <?php endif; ?>
</div>

<div id="content-result">
<?php if ($isGenerating): ?>
    <?php include __DIR__ . '/partials/generating.php'; ?>
<?php endif; ?>
</div>
<div id="critique-result"></div>

<?php if ($latestVersion):
    $contentData = json_decode($latestVersion['content'], true);
    $contentText = is_array($contentData) ? ($contentData['text'] ?? '') : $latestVersion['content'];
    ?>
<h2>Content (Version <?= $latestVersion['version_number'] ?>)</h2>
<div class="result-box">
    <div class="result-box__header">
        <strong>Version <?= $latestVersion['version_number'] ?></strong>
        <span><?= date('d.m.Y H:i', strtotime($latestVersion['created_at'])) ?></span>
    </div>
    <div class="result-box__content">
        <pre><?= htmlspecialchars($contentText) ?></pre>
    </div>
</div>
<?php endif; ?>

<?php if (!empty($critiques)): ?>
<h2>Kritiken</h2>
<table data-sortable>
    <thead>
        <tr>
            <th data-sort="round">Runde</th>
            <th data-sort="critic">Kritiker</th>
            <th data-sort="rating">Bewertung</th>
            <th data-sort="status">Status</th>
            <th data-sort="summary">Zusammenfassung</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($critiques as $c): ?>
        <tr>
            <td><?= $c['round'] ?? '-' ?></td>
            <td><?= htmlspecialchars($c['critic_name'] ?? '-') ?></td>
            <td><?= $c['rating'] ?? '-' ?>/10</td>
            <td><span class="badge badge--<?= ($c['passed'] ?? false) ? 'completed' : 'failed' ?>"><?= ($c['passed'] ?? false) ? 'Bestanden' : 'Offen' ?></span></td>
            <td><?= htmlspecialchars($c['summary'] ?? '-') ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>
<?php endif; ?>

<?php if (!empty($sources)): ?>
<h2>Quellen (RAG)</h2>
<table data-sortable>
    <thead>
        <tr>
            <th data-sort="document">Dokument</th>
            <th data-sort="score">Relevanz</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($sources as $s): ?>
        <tr>
            <td><?= htmlspecialchars($s['document_name'] ?? 'Unbekannt') ?></td>
            <td><?= round(($s['relevance_score'] ?? 0) * 100) ?>%</td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>
<?php endif; ?>

<?php if (count($versions) > 1): ?>
<h2>Versionshistorie</h2>
<table data-sortable>
    <thead>
        <tr>
            <th data-sort="version">Version</th>
            <th data-sort="created">Erstellt</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($versions as $v): ?>
        <tr>
            <td>V<?= $v['version_number'] ?></td>
            <td><?= date('d.m.Y H:i', strtotime($v['created_at'])) ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>
<?php endif; ?>

<p style="margin-top: 2rem;"><a href="/content">&larr; Zurück zur Übersicht</a></p>

<style>
.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-md); margin-bottom: var(--space-lg); }
.info-card { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 8px; padding: var(--space-md); }
.info-card h3 { margin: 0 0 var(--space-sm) 0; font-size: 0.9rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.info-list { display: grid; grid-template-columns: auto 1fr; gap: var(--space-xs) var(--space-sm); margin: 0; }
.info-list dt { color: var(--color-text-muted); font-size: 0.85rem; }
.info-list dd { margin: 0; font-weight: 500; }
.briefing-box { background: var(--color-bg-muted); border-radius: 8px; padding: var(--space-md); margin-bottom: var(--space-lg); line-height: 1.6; }

/* Action Cards - Vertical Stack */
.action-cards {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
    max-width: 500px;
}
.action-card {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: var(--space-md);
    display: flex;
    flex-direction: column;
}
.action-card--primary {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 1px var(--color-primary);
}
.action-card__header {
    font-weight: 600;
    font-size: 0.95rem;
    margin-bottom: var(--space-xs);
    color: var(--color-text);
}
.action-card__desc {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-bottom: var(--space-sm);
    line-height: 1.4;
}
.action-card__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin-top: auto;
}
.action-card__buttons {
    display: flex;
    gap: var(--space-xs);
}
.action-card__buttons .btn {
    flex: 1;
}
.action-link {
    color: var(--color-primary);
    text-decoration: none;
}
.action-link:hover {
    text-decoration: underline;
}

/* Form Elements in Cards */
.form-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.form-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.form-select {
    padding: 0.5rem 0.75rem;
    font-size: 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    background: var(--color-bg);
    color: var(--color-text);
    width: 100%;
}
.btn--full {
    width: 100%;
    justify-content: center;
}

/* Button Loading Animation */
.generate-btn .btn-text,
.critique-btn .btn-text,
.revise-btn .btn-text { display: inline; }
.generate-btn .btn-loading,
.critique-btn .btn-loading,
.revise-btn .btn-loading { display: none; gap: 3px; justify-content: center; align-items: center; }
.generate-btn.is-loading .btn-text,
.critique-btn.is-loading .btn-text,
.revise-btn.is-loading .btn-text { display: none; }
.generate-btn.is-loading .btn-loading,
.critique-btn.is-loading .btn-loading,
.revise-btn.is-loading .btn-loading { display: inline-flex; }
.generate-btn .btn-loading span,
.critique-btn .btn-loading span,
.revise-btn .btn-loading span {
    width: 6px; height: 6px;
    background: currentColor;
    border-radius: 50%;
    animation: btn-bounce 1.4s infinite ease-in-out both;
}
.generate-btn .btn-loading span:nth-child(1),
.critique-btn .btn-loading span:nth-child(1),
.revise-btn .btn-loading span:nth-child(1) { animation-delay: -0.32s; }
.generate-btn .btn-loading span:nth-child(2),
.critique-btn .btn-loading span:nth-child(2),
.revise-btn .btn-loading span:nth-child(2) { animation-delay: -0.16s; }
.generate-btn .btn-loading span:nth-child(3),
.critique-btn .btn-loading span:nth-child(3),
.revise-btn .btn-loading span:nth-child(3) { animation-delay: 0s; }
@keyframes btn-bounce {
    0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
    40% { transform: scale(1); opacity: 1; }
}
</style>

<script>
document.body.addEventListener('htmx:beforeRequest', function(evt) {
    var form = evt.detail.elt;
    var btnClass = null;
    if (form.classList.contains('generate-form')) btnClass = '.generate-btn';
    if (form.classList.contains('critique-form')) btnClass = '.critique-btn';
    if (form.classList.contains('revise-form')) btnClass = '.revise-btn';

    if (btnClass) {
        var btn = form.querySelector(btnClass);
        if (btn) {
            btn.disabled = true;
            btn.classList.add('is-loading');
        }
        // Show loading info in target
        var targetId = form.getAttribute('hx-target');
        if (targetId === '#critique-result') {
            document.getElementById('critique-result').innerHTML =
                '<div class="loading-box">' +
                '<div class="loading-spinner"><span></span><span></span><span></span></div>' +
                '<p><strong>Kritiker analysieren Content...</strong></p>' +
                '<p class="loading-info">Faktenpruefer, Stilist und Strukturanalyst pruefen den Text. Dies dauert 30-120 Sekunden.</p>' +
                '</div>';
        }
    }
});
</script>

<style>
.loading-box {
    background: var(--color-bg-muted);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: var(--space-lg);
    text-align: center;
    margin: var(--space-md) 0;
}
.loading-spinner {
    display: inline-flex;
    gap: 4px;
    margin-bottom: var(--space-sm);
}
.loading-spinner span {
    width: 10px; height: 10px;
    background: var(--color-primary);
    border-radius: 50%;
    animation: btn-bounce 1.4s infinite ease-in-out both;
}
.loading-spinner span:nth-child(1) { animation-delay: -0.32s; }
.loading-spinner span:nth-child(2) { animation-delay: -0.16s; }
.loading-spinner span:nth-child(3) { animation-delay: 0s; }
.loading-info {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    margin-top: var(--space-xs);
}
</style>

<?php $content = ob_get_clean(); ?>
<?php require VIEW_PATH . '/layout.php'; ?>

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
2150 38 modified 11.7 KB 2025-12-30 20:51
1924 37 modified 11.7 KB 2025-12-28 01:20
1692 36 modified 11.6 KB 2025-12-27 12:10
1691 35 modified 11.6 KB 2025-12-27 12:10
1690 34 modified 11.5 KB 2025-12-27 12:09
1017 33 modified 12.1 KB 2025-12-24 01:31
1010 32 modified 12.1 KB 2025-12-24 01:26
1009 31 modified 12.1 KB 2025-12-24 01:26
1008 30 modified 12.1 KB 2025-12-24 01:26
1007 29 modified 12.1 KB 2025-12-24 01:26
1006 28 modified 12.1 KB 2025-12-24 01:26
1005 27 modified 12.1 KB 2025-12-24 01:25
998 26 modified 16.7 KB 2025-12-24 01:21
996 25 modified 16.5 KB 2025-12-24 01:17
995 24 modified 14.4 KB 2025-12-24 01:17
994 23 modified 14.2 KB 2025-12-24 01:16
992 22 modified 14.2 KB 2025-12-24 01:15
991 21 modified 12.8 KB 2025-12-24 01:11
990 20 modified 10.5 KB 2025-12-24 01:10
983 19 modified 10.6 KB 2025-12-24 00:16
982 18 modified 10.7 KB 2025-12-24 00:16
981 17 modified 10.6 KB 2025-12-24 00:16
980 16 modified 10.5 KB 2025-12-24 00:15
979 15 modified 10.4 KB 2025-12-24 00:15
978 14 modified 9.3 KB 2025-12-24 00:15
977 13 modified 8.9 KB 2025-12-24 00:15
204 12 modified 9.1 KB 2025-12-21 14:46
192 11 modified 8.9 KB 2025-12-21 14:37
179 10 modified 9.3 KB 2025-12-21 09:14
176 9 modified 9.2 KB 2025-12-21 04:14
175 8 modified 9.2 KB 2025-12-21 04:14
174 7 modified 8.9 KB 2025-12-21 04:14
162 6 modified 7.8 KB 2025-12-21 03:01
161 5 modified 6.5 KB 2025-12-21 03:01
99 4 modified 6.4 KB 2025-12-20 19:18
98 3 modified 6.4 KB 2025-12-20 19:17
97 2 modified 6.4 KB 2025-12-20 19:17
96 1 modified 6.4 KB 2025-12-20 19:17

← Zurück zur Übersicht