Files
geograsim/App/php/api/tickets.php
T
Adminator 9a61f55cb1 Atlas: Infrastruktur + Team-Konventionen + Sprachregel Lernarbeit
- Design-System (assets/css/design-system.css) mit 21 Komponenten,
  iPad-Responsive-Breakpoints, Touch-Ziele 36px, Music-Player,
  Glossar-Tooltips
- Templates (sims/template.html + student/teacher-Dashboard)
- Docs: module-interface.md (inkl. 4a Sprachregel, 4b Leichte Sprache,
  4c iPad), content-architecture.md, crash-recovery.md, music-registry.md
- Admin-Infrastruktur: admin-modules.html + api/admin-modules.php
  (Titel, Emoji, Bild, Status, Dauer, Alter pro Modul)
- Inbox-System: _inbox/README.md + _status.md fuer Atlas + Briefings
  an Klima, Glossar, Lehrplan, Fluss
- Zentrale SFX-Pipeline (scripts/generate-sounds.py)
- DALL-E-Bilder: 8 Badges + 5 Glossar-Repraesentationsbilder (Querformat)
- Logo + Inter-Font lokal
- PHP-APIs: admin, glossar, levels, licenses, progress, waypoints,
  assignments, profile, tickets
- Spielsprache entfernt (admin-modules, admin-levels, schueler)
- Landing-Page-Bearbeitungen (Boote sichtbarer, Button-Hintergrund)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 11:51:14 +02:00

95 lines
4.1 KiB
PHP

<?php
/**
* API: Einladungstickets (druckbare HTML-Seite)
* GET /api/tickets?class_id=X → Druckbare Zugangskarten fuer alle Schueler der Klasse
*/
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
Response::error('Nur GET erlaubt', 405);
}
$teacherId = Session::requireTeacher();
$db = Database::get();
$classId = (int)($_GET['class_id'] ?? 0);
if (!$classId) Response::error('class_id erforderlich');
$class = $db->fetchOne(
'SELECT id, name, school_year, join_code FROM classes WHERE id = ? AND teacher_id = ?',
[$classId, $teacherId]
);
if (!$class) Response::error('Klasse nicht gefunden', 404);
$students = $db->fetchAll(
'SELECT username, display_name, emoji_avatar FROM students WHERE class_id = ? ORDER BY username',
[$classId]
);
// Druckbare HTML-Seite ausgeben (kein JSON)
header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Zugangskarten — <?= htmlspecialchars($class['name']) ?></title>
<style>
@page { size: A4; margin: 10mm; }
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Inter', 'Segoe UI', system-ui, sans-serif; background: #fff; color: #1a1a1a; }
.print-header { text-align: center; padding: 1rem 0 .5rem; border-bottom: 2px solid #4a7c8a; margin-bottom: 1rem; }
.print-header h1 { font-size: 1.1rem; color: #4a7c8a; }
.print-header p { font-size: .75rem; color: #8a8a8a; }
.tickets { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8mm; }
.ticket {
border: 2px solid #4a7c8a; border-radius: 10px; padding: 10px;
page-break-inside: avoid; position: relative; min-height: 140px;
}
.ticket-top { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; border-bottom: 1px dashed #dae8ec; padding-bottom: 6px; }
.ticket-emoji { font-size: 1.8rem; }
.ticket-brand { font-size: .6rem; font-weight: 800; color: #4a7c8a; letter-spacing: .02em; }
.ticket-class { font-size: .55rem; color: #8a8a8a; }
.ticket-row { display: flex; gap: 4px; margin-bottom: 4px; font-size: .7rem; }
.ticket-label { color: #8a8a8a; font-weight: 500; min-width: 80px; }
.ticket-val { font-weight: 700; font-family: 'Courier New', monospace; letter-spacing: .04em; }
.ticket-hint { font-size: .55rem; color: #aaa; margin-top: 6px; text-align: center; }
.ticket-url { font-size: .55rem; color: #4a7c8a; text-align: center; margin-top: 4px; font-weight: 600; }
.no-print { text-align: center; padding: 1rem; }
.no-print button { padding: .5rem 1.5rem; background: #4a7c8a; color: #fff; border: none; border-radius: 8px; font-size: .85rem; font-weight: 700; cursor: pointer; margin: 0 .3rem; }
.no-print button:hover { background: #3a6470; }
@media print {
.no-print { display: none; }
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
</style>
</head>
<body>
<div class="no-print">
<button onclick="window.print()">Drucken / als PDF speichern</button>
<button onclick="window.close()">Schliessen</button>
</div>
<div class="print-header">
<h1>GeoGraSim — Zugangskarten</h1>
<p>Klasse <?= htmlspecialchars($class['name']) ?> · <?= htmlspecialchars($class['school_year']) ?> · Code: <?= htmlspecialchars($class['join_code']) ?></p>
</div>
<div class="tickets">
<?php foreach ($students as $s): ?>
<div class="ticket">
<div class="ticket-top">
<span class="ticket-emoji"><?= $s['emoji_avatar'] ?: '🧑‍🎓' ?></span>
<div>
<div class="ticket-brand">GeoGraSim</div>
<div class="ticket-class">Klasse <?= htmlspecialchars($class['name']) ?></div>
</div>
</div>
<div class="ticket-row"><span class="ticket-label">Klassencode:</span><span class="ticket-val"><?= htmlspecialchars($class['join_code']) ?></span></div>
<div class="ticket-row"><span class="ticket-label">Benutzer:</span><span class="ticket-val"><?= htmlspecialchars($s['username']) ?></span></div>
<div class="ticket-row"><span class="ticket-label">Passwort:</span><span class="ticket-val">****</span></div>
<div class="ticket-hint">Passwort wurde bei der Erstellung angezeigt.</div>
<div class="ticket-url">geograsim.at</div>
</div>
<?php endforeach; ?>
</div>
</body>
</html>
<?php exit;