Files
phpsite/requests.php
alex 8c069ee82a Add usernames and sudo_usernames fields to VM request form
- DB: add usernames/sudo_usernames columns to vm_requests table
- create.php: add form inputs for usernames and sudo_usernames
- send.php: capture, validate, and store both fields in DB
- netbox_integration/netbox_api.php: pass custom_fields to NetBox VM API
- requests.php: show usernames/sudo_usernames in request list
2026-05-09 23:57:36 +02:00

161 lines
7.8 KiB
PHP

<?php
require __DIR__ . '/config.php';
require_login();
/* ---- Pagination ---- */
$page = max(1, (int) ($_GET['page'] ?? 1));
$perPage = 12;
$offset = ($page - 1) * $perPage;
$totalStmt = db()->query('SELECT COUNT(*) FROM vm_requests');
$total = (int) $totalStmt->fetchColumn();
$totalPages = max(1, (int) ceil($total / $perPage));
if ($page > $totalPages) $page = $totalPages;
$stmt = db()->prepare(
'SELECT id, vm_name, domain_name, size, vcpus, ram_gb, disk_gb, status, description, usernames, sudo_usernames, created_at, netbox_device_id
FROM vm_requests
ORDER BY created_at DESC
LIMIT :limit OFFSET :offset'
);
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$recentRequests = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Requests</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/style.css">
</head>
<body>
<main class="shop-page">
<nav class="topbar">
<div>
<p class="eyebrow">Infrastructure Portal</p>
<a href="/index.php" style="text-decoration:none;color:inherit;">
<h1>VM Shop</h1>
</a>
</div>
<div class="nav-links">
<a href="/index.php" class="nav-link">Shop</a>
<a href="/requests.php" class="nav-link active">My Requests</a>
<a class="link-button" href="/logout.php">&larr; Logout</a>
</div>
</nav>
<?php if (!empty($_GET['cancelled'])): ?>
<div class="success-message">&#10003; VM request cancelled.</div>
<?php endif; ?>
<section class="panel requests-panel">
<div class="requests-header">
<h2 style="margin:0">My VM Requests</h2>
<a href="/index.php" class="btn btn-primary btn-sm">+ New Request</a>
</div>
<?php if (!$recentRequests): ?>
<div class="empty-state">
<div class="empty-state-icon">&#128640;</div>
<p class="muted">No VM requests yet.<br><a href="/index.php">Order your first VM &rarr;</a></p>
</div>
<?php else: ?>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Name</th>
<th>Domain</th>
<th>Specs</th>
<th>Status</th>
<th>When</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($recentRequests as $request): ?>
<tr>
<td>
<strong><?= h($request['vm_name']) ?></strong>
<?php if (!empty($request['description'])): ?>
<div class="muted" style="font-size:0.75rem;margin-top:2px;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="<?= h($request['description']) ?>">
<?= h($request['description']) ?>
</div>
<?php endif; ?>
<?php if (!empty($request['usernames'])): ?>
<div style="font-size:0.75rem;margin-top:3px;color:var(--text-secondary);">
Users: <strong><?= h($request['usernames']) ?></strong>
<?php if (!empty($request['sudo_usernames'])): ?>
<span style="color:var(--warning-text);font-weight:600;">| sudo: <?= h($request['sudo_usernames']) ?></span>
<?php endif; ?>
</div>
<?php endif; ?>
</td>
<td><?= h($request['domain_name']) ?></td>
<td>
<span class="badge badge-<?= h($request['size']) ?>" style="font-size:0.7rem;padding:2px 8px;">
<?= h(ucfirst($request['size'])) ?>
</span>
<span class="muted" style="font-size:0.78rem;margin-left:6px;">
<?= h((string) $request['vcpus']) ?>c / <?= h((string) $request['ram_gb']) ?>G
</span>
</td>
<td>
<span class="badge badge-<?= h($request['status']) ?>">
<span class="badge-dot"></span>
<?= h(ucfirst(str_replace('_', ' ', $request['status']))) ?>
</span>
</td>
<td class="td-timestamp">
<?= h(date('M j, Y', strtotime($request['created_at']))) ?>
<br>
<span style="opacity:0.6"><?= h(date('g:i A', strtotime($request['created_at']))) ?></span>
</td>
<td class="td-actions">
<?php if ($request['status'] === 'queued'): ?>
<form action="/cancel.php" method="post" style="display:inline" onsubmit="return confirm('Cancel this request?');">
<input type="hidden" name="csrf_token" value="<?= h(csrf_token()) ?>">
<input type="hidden" name="id" value="<?= (int) $request['id'] ?>">
<button type="submit" class="cancel-btn" title="Cancel request">Cancel</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php if ($request['netbox_device_id']): ?>
<tr style="background:var(--success-bg)">
<td colspan="6" style="font-size:0.78rem;color:var(--success-text);padding-top:4px;padding-bottom:8px;">
&#9989; NetBox Device #<?= h((string) $request['netbox_device_id']) ?>
</td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php if ($totalPages > 1): ?>
<nav class="pagination" aria-label="Requests pagination">
<?php if ($page > 1): ?>
<a class="pagination-link" href="/requests.php?page=<?= $page - 1 ?>">&larr; Prev</a>
<?php else: ?>
<span class="pagination-link disabled">&larr; Prev</span>
<?php endif; ?>
<span class="pagination-info">Page <?= $page ?> of <?= $totalPages ?> (<?= $total ?> total)</span>
<?php if ($page < $totalPages): ?>
<a class="pagination-link" href="/requests.php?page=<?= $page + 1 ?>">Next &rarr;</a>
<?php else: ?>
<span class="pagination-link disabled">Next &rarr;</span>
<?php endif; ?>
</nav>
<?php endif; ?>
<?php endif; ?>
</section>
</main>
</body>
</html>