Initial Release: Lütte Planer mit Google-Login-Vorbereitung
- Login-System (Mock für Tests, Google OAuth vorbereitet) - Reisen erstellen mit Emoji, Ziel und Datum - Ablauf (Timeline), Packliste, Ideen, Notizen, Dokumente - Team-System: Personen einladen per E-Mail + Einladungslinks - Berechtigungen: Nur lesen / Bearbeiten / Admin - E-Mail-Benachrichtigungen beim Einladen Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
$tripId = $_GET['trip'] ?? '';
|
||||
[$trip, $user] = requireTripAccess($tripId);
|
||||
$canEdit = userCanEdit($tripId, $user['id']);
|
||||
global $UPLOAD_TYPEN;
|
||||
|
||||
$uploadDir = UPLOAD_DIR . $tripId . '/';
|
||||
|
||||
// Upload
|
||||
if ($canEdit && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['upload'])) {
|
||||
$file = $_FILES['datei'] ?? null;
|
||||
$name = trim($_POST['name'] ?? '') ?: ($file['name'] ?? '');
|
||||
if ($file && $file['error'] === UPLOAD_ERR_OK && $name) {
|
||||
$mime = mime_content_type($file['tmp_name']);
|
||||
if (isset($UPLOAD_TYPEN[$mime]) && $file['size'] <= UPLOAD_MAX_MB * 1024 * 1024) {
|
||||
if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);
|
||||
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
|
||||
$filename = uniqid('doc_') . '.' . $ext;
|
||||
if (move_uploaded_file($file['tmp_name'], $uploadDir . $filename)) {
|
||||
dbInsert('dokumente', ['trip_id' => $tripId, 'name' => $name, 'dateiname' => $filename, 'mime_type' => $mime, 'groesse' => $file['size'], 'created_by' => $user['id']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
header('Location: /Develop/PlanerGoogel/dokumente.php?trip=' . $tripId); exit;
|
||||
}
|
||||
|
||||
// Löschen
|
||||
if ($canEdit && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete'])) {
|
||||
$doc = dbOne('SELECT * FROM dokumente WHERE id = ? AND trip_id = ?', [(int)$_POST['delete'], $tripId]);
|
||||
if ($doc) {
|
||||
@unlink($uploadDir . $doc['dateiname']);
|
||||
dbExec('DELETE FROM dokumente WHERE id = ?', [$doc['id']]);
|
||||
}
|
||||
header('Location: /Develop/PlanerGoogel/dokumente.php?trip=' . $tripId); exit;
|
||||
}
|
||||
|
||||
// Download
|
||||
if (isset($_GET['dl'])) {
|
||||
$doc = dbOne('SELECT * FROM dokumente WHERE id = ? AND trip_id = ?', [(int)$_GET['dl'], $tripId]);
|
||||
if ($doc && file_exists($uploadDir . $doc['dateiname'])) {
|
||||
header('Content-Type: ' . $doc['mime_type']);
|
||||
header('Content-Disposition: attachment; filename="' . addslashes($doc['name']) . '"');
|
||||
readfile($uploadDir . $doc['dateiname']); exit;
|
||||
}
|
||||
http_response_code(404); exit;
|
||||
}
|
||||
|
||||
$docs = dbAll('SELECT d.*, u.name as user_name FROM dokumente d LEFT JOIN users u ON u.id = d.created_by WHERE d.trip_id = ? ORDER BY d.created_at DESC', [$tripId]);
|
||||
|
||||
function formatSize(int $bytes): string {
|
||||
if ($bytes < 1024) return $bytes . ' B';
|
||||
if ($bytes < 1048576) return round($bytes / 1024, 1) . ' KB';
|
||||
return round($bytes / 1048576, 1) . ' MB';
|
||||
}
|
||||
|
||||
$pageTitle = 'Dokumente';
|
||||
$activeTab = 'dokumente';
|
||||
include __DIR__ . '/includes/header.php';
|
||||
?>
|
||||
|
||||
<main class="main">
|
||||
<div class="page-header">
|
||||
<h1 class="section-head">Dokumente</h1>
|
||||
<?php if ($canEdit): ?>
|
||||
<button class="btn btn-primary" onclick="toggleForm('add-form')">+ Upload</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($canEdit): ?>
|
||||
<div id="add-form" class="add-form hidden">
|
||||
<form method="POST" enctype="multipart/form-data" style="display:contents;">
|
||||
<input type="text" name="name" placeholder="Bezeichnung (optional)">
|
||||
<input type="file" name="datei" accept="<?= UPLOAD_ACCEPT ?>" required style="flex:1;">
|
||||
<button type="submit" name="upload" class="btn btn-primary">Hochladen</button>
|
||||
</form>
|
||||
<div style="width:100%;font-size:.72rem;color:var(--muted);margin-top:-8px;">Max. <?= UPLOAD_MAX_MB ?> MB · PDF, JPG, PNG, Word</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($docs)): ?>
|
||||
<div class="empty"><div class="empty-icon">📁</div><p>Noch keine Dokumente hochgeladen.</p></div>
|
||||
<?php else: ?>
|
||||
<div class="doc-list">
|
||||
<?php foreach ($docs as $doc):
|
||||
$icon = str_contains($doc['mime_type'], 'pdf') ? '📄' : (str_contains($doc['mime_type'], 'image') ? '🖼️' : '📎');
|
||||
?>
|
||||
<div class="doc-item">
|
||||
<span class="doc-icon"><?= $icon ?></span>
|
||||
<div class="doc-info">
|
||||
<div class="doc-name"><?= h($doc['name']) ?></div>
|
||||
<div class="doc-meta"><?= formatSize((int)$doc['groesse']) ?> · <?= date('d.m.Y', $doc['created_at']) ?><?= $doc['user_name'] ? ' · ' . h($doc['user_name']) : '' ?></div>
|
||||
</div>
|
||||
<div class="doc-actions">
|
||||
<a href="/Develop/PlanerGoogel/dokumente.php?trip=<?= $tripId ?>&dl=<?= $doc['id'] ?>" class="btn-edit">⬇ Download</a>
|
||||
<?php if ($canEdit): ?>
|
||||
<form method="POST" onsubmit="return confirm('Dokument löschen?')" style="display:inline;">
|
||||
<button type="submit" name="delete" value="<?= $doc['id'] ?>" class="btn-delete">✕</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<?php include __DIR__ . '/includes/footer.php'; ?>
|
||||
Reference in New Issue
Block a user