design anpassung

This commit is contained in:
2026-06-23 00:06:31 +02:00
parent 1891ec0a51
commit cbea23083d
30 changed files with 785 additions and 547 deletions
+7 -7
View File
@@ -49,7 +49,7 @@ final class PlatformController
}
$this->view->render('home/index', [
'title' => 'Kaffeekasse fuer Teams, Vereine und Coworking',
'title' => 'Kaffeeliste für Teams, Vereine und Büroküchen',
'setupComplete' => $setup->isInstalled(),
'stats' => $stats,
'allowPublicRegistration' => $this->config['allow_public_registration'] ?? false,
@@ -77,7 +77,7 @@ final class PlatformController
try {
$setup->install($_POST);
$this->session->flash('success', 'Die Installation wurde abgeschlossen. Jetzt kannst du dich als Plattform-Admin anmelden.');
$this->session->flash('success', 'Die Installation wurde abgeschlossen. Sie können sich jetzt als Plattform-Administrator anmelden.');
Response::redirect('/admin/login');
} catch (\Throwable $throwable) {
remember_old_input($_POST);
@@ -93,12 +93,12 @@ final class PlatformController
}
if (!$this->allowsPublicRegistration()) {
$this->session->flash('error', 'Die offene Registrierung ist derzeit deaktiviert. Fuer einen Pilotzugang bitte direkt den Betreiber kontaktieren.');
$this->session->flash('error', 'Die offene Registrierung ist derzeit deaktiviert. Bitte kontaktieren Sie den Betreiber.');
Response::redirect('/');
}
$this->view->render('home/register', [
'title' => 'Mandant registrieren',
'title' => 'Kaffeeliste registrieren',
]);
}
@@ -122,7 +122,7 @@ final class PlatformController
$service = new TenantRegistrationService($pdo, $audit);
$slug = $service->register($_POST);
$this->clearScopes($rateLimiter, 'registration', $scopes);
$this->session->flash('success', 'Dein Mandant wurde angelegt. Du kannst dich jetzt anmelden.');
$this->session->flash('success', 'Die Kaffeeliste wurde angelegt. Sie können sich jetzt anmelden.');
Response::redirect('/t/' . rawurlencode($slug) . '/login');
} catch (\Throwable $throwable) {
if ($this->database->isConfigured()) {
@@ -141,7 +141,7 @@ final class PlatformController
public function adminLoginForm(): void
{
$this->view->render('admin/login', [
'title' => 'Plattform-Login',
'title' => 'Kaffeelisten verwalten',
]);
}
@@ -257,7 +257,7 @@ final class PlatformController
$passwordConfirm = (string) ($_POST['password_confirm'] ?? '');
if ($password !== $passwordConfirm) {
throw new RuntimeException('Die Passwort-Bestaetigung stimmt nicht ueberein.');
throw new RuntimeException('Die Passwort-Bestätigung stimmt nicht überein.');
}
$pdo = $this->database->pdo();
+34 -31
View File
@@ -33,7 +33,7 @@ final class TenantController
$tenant = $this->tenant($tenantSlug);
$this->view->render('tenant/login', [
'title' => 'Tenant-Login',
'title' => 'Kaffeelisten-Login',
'tenant' => $tenant,
]);
}
@@ -67,11 +67,11 @@ final class TenantController
if (!$this->isTenantManager($authState) && !$this->selfServiceAllowed((int) $tenant['id'])) {
$auth->logout();
throw new RuntimeException('Die digitale Selbstbuchung ist fuer diesen Mandanten derzeit deaktiviert.');
throw new RuntimeException('Die Buchung ist für diese Kaffeeliste derzeit deaktiviert.');
}
$this->clearRateLimitScopes($rateLimiter, $scopes);
$this->session->flash('success', 'Willkommen zur digitalen Kaffeeliste.');
$this->session->flash('success', 'Willkommen in Ihrer Kaffeeliste.');
Response::redirect(tenant_url($tenantSlug));
} catch (\Throwable $throwable) {
remember_old_input($_POST);
@@ -86,7 +86,7 @@ final class TenantController
$pdo = $this->database->pdo();
$auth = new Auth($pdo, $this->session);
$auth->logout();
$this->session->flash('success', 'Du wurdest abgemeldet.');
$this->session->flash('success', 'Sie wurden abgemeldet.');
Response::redirect(tenant_url($tenantSlug, 'login'));
}
@@ -125,6 +125,7 @@ final class TenantController
m.display_name AS member_name,
p.name AS product_name,
s.name AS source_name,
s.code AS source_code,
CASE WHEN reversal.id IS NULL THEN 0 ELSE 1 END AS is_reversed
FROM consumption_events c
INNER JOIN members m ON m.id = c.member_id
@@ -159,7 +160,7 @@ final class TenantController
$balancesStatement->execute(['tenant_id' => $tenant['id']]);
} else {
if ($currentMember === null) {
throw new RuntimeException('Fuer diesen Benutzer ist kein aktives Mitglied im Mandanten hinterlegt.');
throw new RuntimeException('Für diesen Benutzer ist kein aktives Mitglied in der Kaffeeliste hinterlegt.');
}
$summaryStatement = $pdo->prepare(
@@ -193,6 +194,7 @@ final class TenantController
m.display_name AS member_name,
p.name AS product_name,
s.name AS source_name,
s.code AS source_code,
CASE WHEN reversal.id IS NULL THEN 0 ELSE 1 END AS is_reversed
FROM consumption_events c
INNER JOIN members m ON m.id = c.member_id
@@ -234,7 +236,7 @@ final class TenantController
}
$this->view->render('tenant/dashboard', [
'title' => 'Dashboard',
'title' => 'Kaffeekasse',
'tenant' => $tenant,
'authState' => $authState,
'summary' => $summary,
@@ -271,11 +273,11 @@ final class TenantController
if ($email !== '') {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new RuntimeException('Die E-Mail-Adresse ist ungueltig.');
throw new RuntimeException('Die E-Mail-Adresse ist ungültig.');
}
if ($loginPassword === '' || mb_strlen($loginPassword) < 12) {
throw new RuntimeException('Fuer Login-faehige Mitglieder ist ein Passwort mit mindestens 12 Zeichen noetig.');
throw new RuntimeException('Für Mitglieder mit Login ist ein Passwort mit mindestens 12 Zeichen nötig.');
}
$existingUserStatement = $pdo->prepare('SELECT id FROM users WHERE email = :email LIMIT 1');
@@ -319,7 +321,7 @@ final class TenantController
]);
(new AuditService($pdo))->log((int) $tenant['id'], (int) $authState['user_id'], 'member.created', 'member', (int) $pdo->lastInsertId(), 'success');
$this->session->flash('success', 'Das Mitglied wurde gespeichert.');
$this->session->flash('success', 'Das Mitglied wurde angelegt.');
} catch (\Throwable $throwable) {
remember_old_input($_POST);
$this->session->flash('error', $throwable->getMessage());
@@ -406,7 +408,7 @@ final class TenantController
$productsStatement->execute(['tenant_id' => $tenant['id']]);
$this->view->render('tenant/products', [
'title' => 'Produkte',
'title' => 'Produkte und Preise',
'tenant' => $tenant,
'authState' => $authState,
'products' => $productsStatement->fetchAll(),
@@ -429,7 +431,7 @@ final class TenantController
if ($action === 'reverse_booking') {
if (!$isManager) {
throw new RuntimeException('Nur Admins duerfen Buchungen stornieren.');
throw new RuntimeException('Nur Administratorinnen und Administratoren dürfen Buchungen stornieren.');
}
$service->reverseLedgerEntry(
@@ -453,7 +455,7 @@ final class TenantController
(float) ($_POST['quantity'] ?? 1),
trim((string) ($_POST['notes'] ?? ''))
);
$this->session->flash('success', 'Die Buchung wurde gespeichert.');
$this->session->flash('success', 'Die Kaffeebuchung wurde gespeichert.');
}
} catch (\Throwable $throwable) {
remember_old_input($_POST);
@@ -472,6 +474,7 @@ final class TenantController
m.display_name AS member_name,
p.name AS product_name,
s.name AS source_name,
s.code AS source_code,
le.id AS ledger_entry_id,
CASE WHEN reversal.id IS NULL THEN 0 ELSE 1 END AS is_reversed
FROM consumption_events c
@@ -492,7 +495,7 @@ final class TenantController
if (!$isManager) {
if ($currentMember === null) {
throw new RuntimeException('Fuer diesen Benutzer ist kein aktives Mitglied im Mandanten hinterlegt.');
throw new RuntimeException('Für diesen Benutzer ist kein aktives Mitglied in der Kaffeeliste hinterlegt.');
}
$sql .= ' AND c.member_id = :member_id';
@@ -505,7 +508,7 @@ final class TenantController
$bookingsStatement->execute($params);
$this->view->render('tenant/bookings', [
'title' => 'Digitale Buchungen',
'title' => 'Kaffee buchen',
'tenant' => $tenant,
'authState' => $authState,
'members' => $members,
@@ -550,7 +553,7 @@ final class TenantController
}
} else {
if ($currentMember === null) {
throw new RuntimeException('Fuer diesen Benutzer ist kein aktives Mitglied im Mandanten hinterlegt.');
throw new RuntimeException('Für diesen Benutzer ist kein aktives Mitglied in der Kaffeeliste hinterlegt.');
}
$memberId = (int) $currentMember['id'];
@@ -614,7 +617,7 @@ final class TenantController
(int) $authState['user_id'],
trim((string) ($_POST['notes'] ?? ''))
);
$this->session->flash('success', 'Die Einzahlung wurde gebucht.');
$this->session->flash('success', 'Die Einzahlung wurde gutgeschrieben.');
}
} catch (\Throwable $throwable) {
remember_old_input($_POST);
@@ -645,7 +648,7 @@ final class TenantController
$paymentsStatement->execute(['tenant_id' => $tenant['id']]);
$this->view->render('tenant/payments', [
'title' => 'Einzahlungen',
'title' => 'Geld einzahlen',
'tenant' => $tenant,
'authState' => $authState,
'members' => $members,
@@ -688,10 +691,10 @@ final class TenantController
trim((string) ($_POST['note'] ?? '')) ?: null,
(int) $authState['user_id']
);
$this->session->flash('success', 'Die Papierlisten-Position wurde gespeichert.');
$this->session->flash('success', 'Der Eintrag aus der Papierliste wurde gespeichert.');
} elseif ($action === 'post_sheet') {
$service->postPaperSheet((int) $tenant['id'], (int) ($_POST['paper_sheet_id'] ?? 0), (int) $authState['user_id']);
$this->session->flash('success', 'Die Papierliste wurde ins Ledger uebernommen.');
$this->session->flash('success', 'Die Papierliste wurde als Buchungen übernommen.');
} elseif ($action === 'reverse_sheet') {
$service->reversePaperSheet(
(int) $tenant['id'],
@@ -699,7 +702,7 @@ final class TenantController
(int) $authState['user_id'],
trim((string) ($_POST['reason'] ?? '')) ?: null
);
$this->session->flash('success', 'Die verbuchte Papierliste wurde storniert.');
$this->session->flash('success', 'Die übernommene Papierliste wurde storniert.');
}
} catch (\Throwable $throwable) {
remember_old_input($_POST);
@@ -745,7 +748,7 @@ final class TenantController
$linesStatement->execute(['tenant_id' => $tenant['id']]);
$this->view->render('tenant/paper-sheets', [
'title' => 'Papierlisten',
'title' => 'Papierliste nachtragen',
'tenant' => $tenant,
'authState' => $authState,
'members' => $members,
@@ -775,7 +778,7 @@ final class TenantController
trim((string) ($_POST['location_label'] ?? '')) ?: null,
(int) $authState['user_id']
);
$this->session->flash('success', 'Das RFID-Geraet wurde vorbereitet. Token: ' . $token);
$this->session->flash('success', 'Der Kartenleser wurde angelegt. Das Geräte-Token wird einmalig angezeigt: ' . $token);
} elseif ($action === 'assign_tag') {
$service->assignTag(
(int) $tenant['id'],
@@ -784,7 +787,7 @@ final class TenantController
trim((string) ($_POST['label'] ?? '')) ?: null,
(int) $authState['user_id']
);
$this->session->flash('success', 'Die RFID-Karte wurde zugewiesen.');
$this->session->flash('success', 'Die Karte wurde zugewiesen.');
}
} catch (\Throwable $throwable) {
remember_old_input($_POST);
@@ -816,7 +819,7 @@ final class TenantController
$events->execute(['tenant_id' => $tenant['id']]);
$this->view->render('tenant/rfid', [
'title' => 'RFID-Roadmap',
'title' => 'Kartenleser einrichten',
'tenant' => $tenant,
'authState' => $authState,
'members' => $members,
@@ -862,7 +865,7 @@ final class TenantController
$tenant = (new TenantContext($pdo))->bySlug($tenantSlug);
if (!$tenant || $tenant['status'] === 'suspended') {
throw new RuntimeException('Der Mandant ist nicht verfuegbar.');
throw new RuntimeException('Die Kaffeeliste ist nicht verfügbar.');
}
return $tenant;
@@ -880,7 +883,7 @@ final class TenantController
}
if ($roles !== [] && !$auth->requireRole($roles)) {
$this->session->flash('error', 'Dafuer fehlen die passenden Rechte.');
$this->session->flash('error', 'Dafür fehlen die passenden Rechte.');
Response::redirect(tenant_url($tenantSlug));
}
@@ -893,7 +896,7 @@ final class TenantController
if (!$this->isTenantManager($authState) && !$this->selfServiceAllowed((int) $tenant['id'])) {
$auth->logout();
$this->session->flash('error', 'Die digitale Selbstbuchung ist fuer diesen Mandanten derzeit deaktiviert.');
$this->session->flash('error', 'Die Buchung ist für diese Kaffeeliste derzeit deaktiviert.');
Response::redirect(tenant_url($tenantSlug, 'login'));
}
@@ -968,18 +971,18 @@ final class TenantController
): int {
if ($this->isTenantManager($authState)) {
if ($postedMemberId <= 0) {
throw new RuntimeException('Bitte ein Mitglied fuer die Buchung auswaehlen.');
throw new RuntimeException('Bitte ein Mitglied für die Buchung auswählen.');
}
return $this->assertMemberIdBelongsToTenant($tenantId, $postedMemberId);
}
if ($currentMember === null) {
throw new RuntimeException('Fuer dieses Konto ist kein buchungsfaehiges Mitglied hinterlegt.');
throw new RuntimeException('Für dieses Konto ist kein buchungsfähiges Mitglied hinterlegt.');
}
if ($postedMemberId > 0 && $postedMemberId !== (int) $currentMember['id']) {
throw new RuntimeException('Du darfst nur fuer dein eigenes Mitglied buchen.');
throw new RuntimeException('Sie dürfen nur für Ihr eigenes Mitglied buchen.');
}
return (int) $currentMember['id'];
@@ -1001,7 +1004,7 @@ final class TenantController
]);
if (!$statement->fetchColumn()) {
throw new RuntimeException('Das angegebene Mitglied gehoert nicht zu diesem Mandanten.');
throw new RuntimeException('Das angegebene Mitglied gehört nicht zu dieser Kaffeeliste.');
}
return $memberId;