Upload via GUI (258 Dateien)

This commit is contained in:
2026-10-16 19:12:15 +00:00
parent 491b87f468
commit 56deade877
50 changed files with 23552 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
<?php
require_once __DIR__ . '/includes/bootstrap.php';
$user = require_customer_login();
$claimError = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$ticketNumber = trim($_POST['ticket_number'] ?? '');
if (!rate_limit_check('customer_ticket_claim', client_ip(), 10, 5)) {
$claimError = 'Zu viele Versuche. Bitte versuchen Sie es in einigen Minuten erneut.';
} elseif ($ticketNumber === '' || strlen($ticketNumber) > 32) {
$claimError = 'Bitte geben Sie eine gültige Ticketnummer ein.';
} elseif (empty($_SESSION['guest_ticket_access'][$ticketNumber])) {
$claimError = 'Öffnen Sie zuerst den persönlichen Ticket-Link aus der E-Mail in diesem Browser und versuchen Sie es danach erneut.';
} else {
$ticketStmt = get_db()->prepare('SELECT id FROM tickets WHERE ticket_number = ?');
$ticketStmt->execute([$ticketNumber]);
$ticketId = (int) $ticketStmt->fetchColumn();
if ($ticketId > 0 && claim_ticket_for_customer(get_db(), $ticketId, $user)) {
flash('success', 'Das Ticket wurde Ihrem Konto hinzugefügt.');
redirect('/dashboard.php');
}
$claimError = 'Ticketnummer nicht gefunden oder die Ticket-E-Mail-Adresse stimmt nicht mit Ihrem Konto überein.';
}
}
$stmt = get_db()->prepare(
"SELECT t.*, p.name AS priority_name, p.color AS priority_color, d.name AS department_name,
(SELECT tt.message FROM ticket_threads tt
WHERE tt.ticket_id = t.id AND tt.is_internal_note = 0
ORDER BY tt.created_at DESC LIMIT 1) AS last_message,
(SELECT tt.created_at FROM ticket_threads tt
WHERE tt.ticket_id = t.id AND tt.is_internal_note = 0
ORDER BY tt.created_at DESC LIMIT 1) AS last_message_at
FROM tickets t
JOIN priorities p ON p.id = t.priority_id
JOIN departments d ON d.id = t.department_id
WHERE t.user_id = ?
ORDER BY COALESCE(last_message_at, t.created_at) DESC"
);
$stmt->execute([$user['id']]);
$tickets = $stmt->fetchAll();
$pageTitle = 'Meine Tickets';
$activePage = 'dashboard';
require __DIR__ . '/includes/header_customer.php';
?>
<div class="topbar">
<div>
<h1>Meine Tickets</h1>
<p class="muted" style="margin:4px 0 0">Verlauf und Status Ihrer aktuellen und bisherigen Supportanfragen.</p>
</div>
<a href="/ticket_new.php" class="btn">+ Neues Ticket</a>
</div>
<div class="card" style="margin-bottom:18px">
<h3>Gast-Ticket zum Konto hinzufügen</h3>
<p class="muted">Öffnen Sie zuerst den persönlichen Ticket-Link aus der Ticket-E-Mail in diesem Browser. Anschließend können Sie das Ticket hier Ihrem Konto hinzufügen, wenn die Ticket-E-Mail-Adresse mit Ihrer Konto-E-Mail-Adresse übereinstimmt.</p>
<?php if ($claimError): ?><div class="flash error"><?= e($claimError) ?></div><?php endif; ?>
<form method="post" style="display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap">
<?= csrf_field() ?>
<div style="flex:1;min-width:220px">
<label for="ticket_number">Ticketnummer</label>
<input type="text" id="ticket_number" name="ticket_number" value="<?= e($_POST['ticket_number'] ?? '') ?>" required>
</div>
<button type="submit" class="btn">Ticket hinzufügen</button>
</form>
</div>
<?php if (!$tickets): ?>
<div class="card empty-state" style="padding:48px 24px">
<div style="width:56px;height:56px;border-radius:50%;background:var(--primary-lt);display:flex;align-items:center;justify-content:center;margin:0 auto 16px">
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 8h8M8 12h8M8 16h5"/></svg>
</div>
<p style="font-weight:600;color:var(--ink);margin:0 0 4px">Noch keine Tickets</p>
<p style="margin:0 0 18px">Sie haben bisher keine Supportanfragen erstellt.</p>
<a href="/ticket_new.php" class="btn">Erstes Ticket erstellen</a>
</div>
<?php else: ?>
<div class="card">
<table>
<thead>
<tr>
<th>Ticket</th>
<th>Betreff &amp; letzte Nachricht</th>
<th>Status</th>
<th>Zuletzt aktiv</th>
</tr>
</thead>
<tbody>
<?php foreach ($tickets as $t): [$label, $color] = status_label($t['status']); ?>
<tr>
<td><a href="/ticket_view.php?n=<?= urlencode($t['ticket_number']) ?>" class="ticket-no">#<?= e($t['ticket_number']) ?></a></td>
<td>
<a href="/ticket_view.php?n=<?= urlencode($t['ticket_number']) ?>" style="font-weight:600"><?= e($t['subject']) ?></a>
<?php if ($t['last_message']): ?>
<div class="muted" style="font-size:.78rem; margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:420px">
<?= e(mb_substr(strip_tags($t['last_message']), 0, 100)) ?><?= mb_strlen(strip_tags($t['last_message'])) > 100 ? '…' : '' ?>
</div>
<?php endif; ?>
</td>
<td><span class="badge" style="background:<?= $color ?>"><?= e($label) ?></span></td>
<td class="muted"><?= format_dt($t['last_message_at'] ?? $t['created_at']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php require __DIR__ . '/includes/footer_customer.php'; ?>