Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => $page_title,
'current_route' => $current_route,
'full_width' => true,
'extra_css' => ['/assets/css/infrastructure.css?v=' . filemtime(dirname(__DIR__, 2) . '/public/assets/css/infrastructure.css')],
]);
?>
<div class="content-header">
<div>
<h1><?= $this->te('Infrastruktur') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item active"><?= $this->te('Infrastruktur') ?></li>
</ol>
</div>
<div class="content-header-actions">
<a href="/infrastructure/cabling" class="btn btn-default btn-sm"><i class="fas fa-network-wired"></i> <?= $this->te('Verkabelungs-Übersicht') ?></a>
<a href="/infrastructure/free-space" class="btn btn-default btn-sm"><i class="fas fa-ruler-vertical"></i> <?= $this->te('Freien Platz suchen') ?></a>
<?php if ($can_admin): ?>
<button type="button" class="btn btn-primary btn-sm" onclick="document.getElementById('inf-rack-modal').style.display='flex'"><i class="fas fa-plus"></i> <?= $this->te('Neues Rack') ?></button>
<?php endif; ?>
</div>
</div>
<div class="page-body">
<div class="kpi-row">
<div class="kpi-col"><div class="small-box bg-info"><div class="inner"><h3><?= (int)$kpis['sites'] ?></h3><p><?= $this->te('Standorte mit Racks') ?></p></div><span class="icon"><i class="fas fa-map-marker-alt"></i></span></div></div>
<div class="kpi-col"><div class="small-box bg-primary"><div class="inner"><h3><?= (int)$kpis['racks'] ?></h3><p><?= $this->te('Racks') ?></p></div><span class="icon"><i class="fas fa-server"></i></span></div></div>
<div class="kpi-col"><div class="small-box bg-success"><div class="inner"><h3><?= (int)$kpis['devices'] ?></h3><p><?= $this->te('Geräte verbaut') ?></p></div><span class="icon"><i class="fas fa-plug"></i></span></div></div>
<div class="kpi-col"><div class="small-box <?= (int)$kpis['offline'] > 0 ? 'bg-danger' : 'bg-secondary' ?>"><div class="inner"><h3><?= (int)$kpis['offline'] ?></h3><p><?= $this->te('Offline') ?></p></div><span class="icon"><i class="fas fa-exclamation-triangle"></i></span></div></div>
</div>
<div class="card card-outline card-primary mb-3">
<div class="filter-card-body">
<form method="GET" action="/infrastructure" class="filter-input-wrap" style="max-width:420px;">
<span class="filter-search-icon">🔍</span>
<input type="search" name="q" class="form-control form-control-sm" value="<?= $this->e($q ?? '') ?>"
placeholder="<?= $this->te('Gerät, Inventar-Nr., MAC, Modell oder Port-Beschriftung…') ?>" autocomplete="off" autofocus>
</form>
<?php if (($q ?? '') !== ''): ?>
<a href="/infrastructure" class="btn btn-sm btn-default"><?= $this->te('Zurücksetzen') ?></a>
<?php endif; ?>
</div>
</div>
<?php if ($searchResults !== null): ?>
<h2 class="inf-section-title"><i class="fas fa-search"></i> <?= $this->te('Suchergebnisse') ?> <span class="inf-hint">– <?= count($searchResults) ?> Treffer für „<?= $this->e($q) ?>"</span></h2>
<?php if (empty($searchResults)): ?>
<div class="empty-state"><div class="empty-icon"><i class="fas fa-search"></i></div><h2><?= $this->te('Keine Treffer') ?></h2><p><?= $this->t('Kein eingebautes Gerät passt zu „') ?><?= $this->e($q) ?>".</p></div>
<?php else: ?>
<div class="table-wrapper">
<table class="data-table">
<thead><tr><th scope="col"><?= $this->te('Gerät') ?></th><th scope="col"><?= $this->te('Standort') ?></th><th scope="col"><?= $this->te('Rack') ?></th><th scope="col"><?= $this->te('Treffer') ?></th></tr></thead>
<tbody>
<?php foreach ($searchResults as $r): ?>
<tr>
<td><a href="/infrastructure/racks/<?= (int)$r['rack_id'] ?>" class="table-link"><strong><?= $this->e($r['name']) ?></strong></a></td>
<td><?= $this->e($r['location']) ?: '<span class="text-muted">–</span>' ?></td>
<td><?= $this->e($r['rack']) ?></td>
<td><?= $r['hint'] !== '' ? '<span class="text-muted">' . $this->e($r['hint']) . '</span>' : '<span class="text-muted">–</span>' ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php elseif (empty($sites)): ?>
<div class="empty-state">
<div class="empty-icon"><i class="fas fa-server"></i></div>
<h2><?= $this->te('Noch keine Infrastruktur dokumentiert') ?></h2>
<p><?= $this->te('Legen Sie Ihr erstes Rack an und wählen Sie dabei den Standort. Danach erscheint der Standort hier in der Übersicht.') ?></p>
<?php if ($can_admin): ?>
<button type="button" class="btn btn-primary" onclick="document.getElementById('inf-rack-modal').style.display='flex'"><i class="fas fa-plus"></i> <?= $this->te('Neues Rack anlegen') ?></button>
<?php endif; ?>
</div>
<?php else: ?>
<h2 class="inf-section-title"><i class="fas fa-map-marker-alt"></i> <?= $this->te('Standorte') ?> <span class="inf-hint"><?= $this->te('– nur Standorte mit Racks') ?></span></h2>
<div class="inf-site-grid">
<?php foreach ($sites as $s): $loc = $s['location']; ?>
<a class="inf-site-card" href="/infrastructure/locations/<?= (int)$loc['id'] ?>">
<div class="inf-site-top">
<span class="inf-site-ic"><i class="fas fa-building"></i></span>
<span class="inf-site-nm"><?= $this->e($loc['name']) ?></span>
</div>
<div class="inf-site-stats">
<div class="st"><span class="n"><?= (int)$s['racks'] ?></span><span class="l"><?= $this->te('Racks') ?></span></div>
<div class="st"><span class="n"><?= (int)$s['devices'] ?></span><span class="l"><?= $this->te('Geräte') ?></span></div>
</div>
<div class="inf-site-foot">
<?php if ((int)$s['offline'] > 0): ?>
<span class="status-pill status-pill--danger"><span class="status-dot status-dot--danger"></span> <?= (int)$s['offline'] ?> offline</span>
<?php else: ?>
<span class="status-pill status-pill--success"><span class="status-dot status-dot--success"></span> <?= $this->te('online') ?></span>
<?php endif; ?>
</div>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php if ($can_admin): ?>
<div class="modal-overlay" id="inf-rack-modal" style="display:none;" onclick="if(event.target===this)this.style.display='none'">
<div class="modal-card">
<div class="modal-header"><h2><?= $this->te('Neues Rack anlegen') ?></h2>
<button aria-label="<?= $this->te('Schließen') ?>" type="button" class="modal-close" onclick="document.getElementById('inf-rack-modal').style.display='none'">×</button></div>
<form method="POST" action="/infrastructure/racks">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="modal-body">
<div class="form-group">
<label for="f-fefb-location_id"><?= $this->te('Standort') ?> <span class="text-danger">*</span></label>
<select id="f-fefb-location_id" name="location_id" class="form-control form-control-sm" required data-searchable>
<option value=""><?= $this->te('— Standort wählen —') ?></option>
<?php foreach ($locationOptions as $o): ?>
<option value="<?= (int)$o['id'] ?>" data-depth="<?= (int)$o['depth'] ?>"><?= str_repeat(' ', (int)$o['depth']) ?><?= $this->e($o['name']) ?></option>
<?php endforeach; ?>
</select>
<?php if (empty($locationOptions)): ?>
<small class="form-text text-muted"><?= $this->te('Es sind noch keine Standorte angelegt. Legen Sie zuerst unter „Standorte" (Tickets/Inventar) einen Standort an.') ?></small>
<?php endif; ?>
</div>
<div class="form-group">
<label><?= $this->te('Name') ?> <span class="text-danger">*</span></label>
<input type="text" name="name" class="form-control form-control-sm" placeholder="<?= $this->te('z. B. SRV-01') ?>" required>
</div>
<div class="inf-form-row-2">
<div class="form-group"><label for="f-fefb-height_u"><?= $this->te('Höhe (HE)') ?></label><input id="f-fefb-height_u" type="number" name="height_u" class="form-control form-control-sm" value="42" min="1" max="60"></div>
<div class="form-group"><label for="f-fefb-numbering"><?= $this->te('Nummerierung') ?></label>
<select id="f-fefb-numbering" name="numbering" class="form-control form-control-sm">
<option value="bottom_up"><?= $this->te('von unten (1 unten)') ?></option>
<option value="top_down"><?= $this->te('von oben (1 oben)') ?></option>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" onclick="document.getElementById('inf-rack-modal').style.display='none'"><?= $this->te('Abbrechen') ?></button>
<button type="submit" class="btn btn-primary"><?= $this->te('Rack anlegen') ?></button>
</div>
</form>
</div>
</div>
<script>
document.addEventListener('keydown', function(e){
if(e.key==='Escape'){ var m=document.getElementById('inf-rack-modal'); if(m) m.style.display='none'; }
});
</script>
<?php endif; ?>