OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

responsibilities.php

14 KB
<?php
$this->layout('layouts/main', [
    'page_title' => 'Meine Verantwortlichkeiten',
    'full_width' => true
]);
?>

<div class="responsibilities-fullwidth">
    <!-- Content Header -->
    <div class="content-header">
        <div>
            <h1><?= $this->te('Meine Verantwortlichkeiten') ?></h1>
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
                <li class="breadcrumb-item active"><?= $this->te('Verantwortlichkeiten') ?></li>
            </ol>
        </div>
    </div>

    <div class="responsibilities-body">
        <!-- Statistiken -->
        <section class="stats-row">
            <div class="stat-card">
                <div class="stat-icon">&#128196;</div>
                <div class="stat-content">
                    <div class="stat-value"><?= $total_count ?? 0 ?></div>
                    <div class="stat-label"><?= $this->te('Seiten gesamt') ?></div>
                </div>
            </div>
            <?php if (($overdue_count ?? 0) > 0): ?>
            <div class="stat-card danger">
                <div class="stat-icon">&#9888;</div>
                <div class="stat-content">
                    <div class="stat-value"><?= $overdue_count ?></div>
                    <div class="stat-label"><?= $this->te('&Uuml;berf&auml;llige Reviews') ?></div>
                </div>
            </div>
            <?php endif; ?>
            <?php if (($upcoming_count ?? 0) > 0): ?>
            <div class="stat-card warning">
                <div class="stat-icon">&#128337;</div>
                <div class="stat-content">
                    <div class="stat-value"><?= $upcoming_count ?></div>
                    <div class="stat-label"><?= $this->te('Reviews in 30 Tagen') ?></div>
                </div>
            </div>
            <?php endif; ?>
        </section>

        <?php if (empty($technical_pages ?? []) && empty($business_pages ?? [])): ?>
        <!-- Empty State -->
        <div class="empty-card">
            <div class="empty-icon">&#128203;</div>
            <h2><?= $this->te('Keine Verantwortlichkeiten') ?></h2>
            <p><?= $this->te('Sie sind derzeit f&uuml;r keine Seiten verantwortlich.') ?></p>
            <a href="/topics" class="btn btn-primary"><?= $this->te('Themengebiete durchsuchen') ?></a>
        </div>
        <?php else: ?>
        <!-- Responsibility Sections -->
        <div class="responsibility-grid">
            <!-- Technische Verantwortung -->
            <section class="responsibility-card">
                <div class="card-header">
                    <h2><?= $this->te('&#128736; Technische Verantwortung') ?></h2>
                    <span class="count-badge"><?= count($technical_pages ?? []) ?></span>
                </div>
                <div class="card-body">
                    <?php if (!empty($technical_pages)): ?>
                    <div class="page-list">
                        <?php foreach ($technical_pages as $page): ?>
                        <?php
                        $isOverdue = !empty($page['next_review_date']) && strtotime($page['next_review_date']) < time();
                        $isUpcoming = !empty($page['next_review_date']) && !$isOverdue && strtotime($page['next_review_date']) < strtotime('+30 days');
                        ?>
                        <a href="/pages/<?= $page['id'] ?>" class="page-item <?= $isOverdue ? 'overdue' : ($isUpcoming ? 'upcoming' : '') ?>">
                            <div class="page-info">
                                <div class="page-title"><?= $this->e($page['title']) ?></div>
                                <div class="page-meta">
                                    <span class="meta-topic"><?= $this->e($page['topic_name']) ?></span>
                                    <?php if (!empty($page['business_owner_name'])): ?>
                                    <span class="meta-owner"><?= $this->te('Fachlich: {person}', ['person' => $page['business_owner_name']]) ?></span>
                                    <?php endif; ?>
                                </div>
                            </div>
                            <div class="page-status">
                                <?php if (!empty($page['next_review_date'])): ?>
                                    <?php if ($isOverdue): ?>
                                        <span class="status-badge badge-danger">
                                            <?= $this->te('&Uuml;berf&auml;llig') ?>
                                            <small><?= date('d.m.Y', strtotime($page['next_review_date'])) ?></small>
                                        </span>
                                    <?php elseif ($isUpcoming): ?>
                                        <span class="status-badge badge-warning">
                                            <?= $this->te('F&auml;llig') ?>
                                            <small><?= date('d.m.Y', strtotime($page['next_review_date'])) ?></small>
                                        </span>
                                    <?php else: ?>
                                        <span class="status-badge badge-default">
                                            <?= date('d.m.Y', strtotime($page['next_review_date'])) ?>
                                        </span>
                                    <?php endif; ?>
                                <?php else: ?>
                                    <span class="status-badge badge-muted"><?= $this->te('Kein Review') ?></span>
                                <?php endif; ?>
                            </div>
                        </a>
                        <?php endforeach; ?>
                    </div>
                    <?php else: ?>
                    <div class="empty-section">
                        <p><?= $this->te('Keine Seiten mit technischer Verantwortung.') ?></p>
                    </div>
                    <?php endif; ?>
                </div>
            </section>

            <!-- Fachliche Verantwortung -->
            <section class="responsibility-card">
                <div class="card-header">
                    <h2><?= $this->te('&#128188; Fachliche Verantwortung') ?></h2>
                    <span class="count-badge"><?= count($business_pages ?? []) ?></span>
                </div>
                <div class="card-body">
                    <?php if (!empty($business_pages)): ?>
                    <div class="page-list">
                        <?php foreach ($business_pages as $page): ?>
                        <?php
                        $isOverdue = !empty($page['next_review_date']) && strtotime($page['next_review_date']) < time();
                        $isUpcoming = !empty($page['next_review_date']) && !$isOverdue && strtotime($page['next_review_date']) < strtotime('+30 days');
                        ?>
                        <a href="/pages/<?= $page['id'] ?>" class="page-item <?= $isOverdue ? 'overdue' : ($isUpcoming ? 'upcoming' : '') ?>">
                            <div class="page-info">
                                <div class="page-title"><?= $this->e($page['title']) ?></div>
                                <div class="page-meta">
                                    <span class="meta-topic"><?= $this->e($page['topic_name']) ?></span>
                                    <?php if (!empty($page['technical_owner_name'])): ?>
                                    <span class="meta-owner"><?= $this->te('Technisch: {person}', ['person' => $page['technical_owner_name']]) ?></span>
                                    <?php endif; ?>
                                </div>
                            </div>
                            <div class="page-status">
                                <?php if (!empty($page['next_review_date'])): ?>
                                    <?php if ($isOverdue): ?>
                                        <span class="status-badge badge-danger">
                                            <?= $this->te('&Uuml;berf&auml;llig') ?>
                                            <small><?= date('d.m.Y', strtotime($page['next_review_date'])) ?></small>
                                        </span>
                                    <?php elseif ($isUpcoming): ?>
                                        <span class="status-badge badge-warning">
                                            <?= $this->te('F&auml;llig') ?>
                                            <small><?= date('d.m.Y', strtotime($page['next_review_date'])) ?></small>
                                        </span>
                                    <?php else: ?>
                                        <span class="status-badge badge-default">
                                            <?= date('d.m.Y', strtotime($page['next_review_date'])) ?>
                                        </span>
                                    <?php endif; ?>
                                <?php else: ?>
                                    <span class="status-badge badge-muted"><?= $this->te('Kein Review') ?></span>
                                <?php endif; ?>
                            </div>
                        </a>
                        <?php endforeach; ?>
                    </div>
                    <?php else: ?>
                    <div class="empty-section">
                        <p><?= $this->te('Keine Seiten mit fachlicher Verantwortung.') ?></p>
                    </div>
                    <?php endif; ?>
                </div>
            </section>
        </div>
        <?php endif; ?>
    </div>
</div>

<style>
.responsibilities-fullwidth {
}

/* Body */
.responsibilities-body {
    padding: 2rem;
    background: var(--slate-50);
    min-height: calc(100vh - 300px);
}

/* Stats Row */
.stats-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 2rem;
    flex-wrap: wrap;
}

.stat-card {
    background: var(--color-bg);
    border-radius: 0.75rem;
    padding: 1.25rem 1.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05);
    min-width: 180px;
}

.stat-card.danger {
    background: linear-gradient(135deg, var(--red-50) 0%, var(--red-100) 100%);
    border: 1px solid var(--red-300);
}

.stat-card.warning {
    background: linear-gradient(135deg, var(--amber-100) 0%, var(--amber-200) 100%);
    border: 1px solid var(--amber-400);
}

.stat-icon {
    font-size: 2rem;
    opacity: 0.8;
}

.stat-value {
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--gray-900);
}

.stat-label {
    font-size: 0.85rem;
    color: var(--gray-500);
}

/* Empty Card */
.empty-card {
    max-width: 400px;
    margin: 4rem auto;
    text-align: center;
    background: var(--color-bg);
    border-radius: 0.75rem;
    padding: 3rem 2rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}

.empty-icon {
    font-size: 4rem;
    opacity: 0.4;
    margin-bottom: 1rem;
}

.empty-card h2 {
    margin: 0 0 0.5rem 0;
    font-size: 1.25rem;
    color: var(--gray-900);
}

.empty-card > p {
    color: var(--gray-500);
    margin-bottom: 1.5rem;
}

.btn-primary {
    display: inline-flex;
    align-items: center;
    padding: 0.625rem 1.25rem;
    background: var(--blue-600);
    color: var(--color-on-accent);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 500;
    transition: all 0.15s;
}

.btn-primary:hover {
    background: var(--blue-700);
}

/* Responsibility Grid */
.responsibility-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
    gap: 1.5rem;
}

.responsibility-card {
    background: var(--color-bg);
    border-radius: 0.75rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05);
    overflow: hidden;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    background: var(--gray-50);
    border-bottom: 1px solid var(--gray-200);
}

.card-header h2 {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: var(--gray-900);
}

.count-badge {
    background: var(--gray-200);
    color: var(--gray-700);
    padding: 0.25rem 0.75rem;
    border-radius: 9999px;
    font-size: 0.8rem;
    font-weight: 600;
}

.card-body {
    padding: 0;
}

/* Page List */
.page-list {
    display: flex;
    flex-direction: column;
}

.page-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    text-decoration: none;
    border-bottom: 1px solid var(--gray-100);
    transition: all 0.15s;
    border-left: 3px solid transparent;
}

.page-item:last-child {
    border-bottom: none;
}

.page-item:hover {
    background: var(--gray-50);
    text-decoration: none;
}

.page-item.overdue {
    border-left-color: var(--red-600);
    background: var(--red-50);
}

.page-item.overdue:hover {
    background: var(--red-100);
}

.page-item.upcoming {
    border-left-color: var(--amber-500);
    background: var(--amber-50);
}

.page-item.upcoming:hover {
    background: var(--amber-100);
}

.page-info {
    flex: 1;
    min-width: 0;
}

.page-title {
    font-weight: 500;
    color: var(--gray-900);
    margin-bottom: 0.25rem;
}

.page-item:hover .page-title {
    color: var(--blue-600);
}

.page-meta {
    display: flex;
    gap: 1rem;
    font-size: 0.8rem;
    color: var(--gray-500);
    flex-wrap: wrap;
}

.page-status {
    flex-shrink: 0;
    margin-left: 1rem;
}

.status-badge {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0.375rem 0.75rem;
    border-radius: 0.375rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-align: center;
}

.status-badge small {
    font-weight: 400;
    opacity: 0.8;
    margin-top: 0.125rem;
}

.badge-danger {
    background: var(--red-50);
    color: var(--red-600);
    border: 1px solid var(--red-300);
}

.badge-warning {
    background: var(--amber-50);
    color: var(--amber-600);
    border: 1px solid var(--amber-400);
}

.badge-default {
    background: var(--gray-100);
    color: var(--gray-600);
}

.badge-muted {
    background: var(--gray-50);
    color: var(--gray-400);
}

/* Empty Section */
.empty-section {
    padding: 2rem;
    text-align: center;
    color: var(--gray-500);
}

/* Responsive */
@media (max-width: 1100px) {
    .responsibility-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 640px) {
    .stats-row {
        flex-direction: column;
    }

    .stat-card {
        min-width: auto;
    }

    .page-item {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.75rem;
    }

    .page-status {
        margin-left: 0;
    }
}
</style>