Frühstückskonten Verwaltung mit PIN-Transaktionshistorie und PDF-Export
This commit is contained in:
@ -1,53 +1,92 @@
|
||||
<%- include('layout', { title: 'Kontodetails - ' + account.name }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Kontodetails: <%= account.name %></h2>
|
||||
|
||||
<div class="account-info">
|
||||
<p><strong>Kontostand:</strong> <span class="balance"><%= account.balance.toFixed(2) %> €</span></p>
|
||||
<p><strong>Erstellt am:</strong> <%= new Date(account.created_at).toLocaleString('de-DE') %></p>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kontodetails - <%= typeof account !== 'undefined' ? account.name : 'Frühstückskonten' %></title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<% if (typeof account !== 'undefined' && account) { %>
|
||||
<h2>Kontodetails: <%= account.name %></h2>
|
||||
|
||||
<div class="account-info">
|
||||
<p><strong>Kontostand:</strong> <span class="balance"><%= account.balance.toFixed(2) %> €</span></p>
|
||||
<p><strong>Erstellt am:</strong> <%= new Date(account.created_at).toLocaleString('de-DE') %></p>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/accounts/<%= account.id %>/deposit" class="btn">Geld einzahlen</a>
|
||||
<a href="/accounts/<%= account.id %>/withdraw" class="btn">Betrag abbuchen</a>
|
||||
<a href="/accounts/<%= account.id %>/pdf" class="btn">PDF Export</a>
|
||||
<% if (typeof isAdmin !== 'undefined' && isAdmin) { %>
|
||||
<a href="/accounts/<%= account.id %>/edit" class="btn secondary">Konto bearbeiten</a>
|
||||
<% } %>
|
||||
<a href="/accounts" class="btn secondary">Zurück zur Liste</a>
|
||||
</div>
|
||||
|
||||
<h3>Transaktionshistorie</h3>
|
||||
<table class="transaction-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Typ</th>
|
||||
<th>Betrag</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Artikel</th>
|
||||
<th>Durchgeführt von</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if (typeof transactions !== 'undefined' && transactions.length > 0) { %>
|
||||
<% transactions.forEach(function(transaction) { %>
|
||||
<tr>
|
||||
<td><%= new Date(transaction.created_at).toLocaleString('de-DE') %></td>
|
||||
<td class="type-<%= transaction.type %>">
|
||||
<%= transaction.type === 'deposit' ? 'Einzahlung' : 'Abbuchung' %>
|
||||
</td>
|
||||
<td class="amount-<%= transaction.type %>">
|
||||
<%= transaction.amount.toFixed(2) %> €
|
||||
</td>
|
||||
<td><%= transaction.description %></td>
|
||||
<td><%= transaction.item_name || '-' %></td>
|
||||
<td><%= transaction.created_by_name || 'System' %></td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
<% } else { %>
|
||||
<tr>
|
||||
<td colspan="6">Keine Transaktionen für dieses Konto.</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% } else { %>
|
||||
<p>Konto nicht gefunden.</p>
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/accounts/<%= account.id %>/deposit" class="btn">Geld einzahlen</a>
|
||||
<a href="/accounts/<%= account.id %>/withdraw" class="btn">Betrag abbuchen</a>
|
||||
<% if (isAdmin) { %>
|
||||
<a href="/accounts/<%= account.id %>/edit" class="btn secondary">Konto bearbeiten</a>
|
||||
<% } %>
|
||||
<a href="/accounts" class="btn secondary">Zurück zur Liste</a>
|
||||
</div>
|
||||
|
||||
<h3>Transaktionshistorie</h3>
|
||||
<table class="transaction-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Typ</th>
|
||||
<th>Betrag</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Artikel</th>
|
||||
<th>Durchgeführt von</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% transactions.forEach(transaction => { %>
|
||||
<tr>
|
||||
<td><%= new Date(transaction.created_at).toLocaleString('de-DE') %></td>
|
||||
<td class="type-<%= transaction.type %>">
|
||||
<%= transaction.type === 'deposit' ? 'Einzahlung' : 'Abbuchung' %>
|
||||
</td>
|
||||
<td class="amount-<%= transaction.type %>">
|
||||
<%= transaction.amount.toFixed(2) %> €
|
||||
</td>
|
||||
<td><%= transaction.description %></td>
|
||||
<td><%= transaction.item_name || '-' %></td>
|
||||
<td><%= transaction.created_by_name || 'System' %></td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<% if (transactions.length === 0) { %>
|
||||
<p>Keine Transaktionen für dieses Konto.</p>
|
||||
<% } %>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,25 +1,60 @@
|
||||
<%- include('layout', { title: 'Konto bearbeiten - ' + account.name }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Konto bearbeiten: <%= account.name %></h2>
|
||||
|
||||
<form action="/accounts/<%= account.id %>", method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" value="<%= account.name %>", required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pin">Neue PIN (4-stellig, leer lassen zum Behalten):</label>
|
||||
<input type="password" id="pin" name="pin" pattern="\d{4}"
|
||||
title="Bitte genau 4 Ziffern eingeben" maxlength="4">
|
||||
</div>
|
||||
<button type="submit" class="btn">Speichern</button>
|
||||
<a href="/accounts/<%= account.id %>", class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<div class="danger-zone">
|
||||
<h4>Achtung: Kontolöschung</h4>
|
||||
<p>Das Löschen eines Kontos löscht auch alle zugehörigen Transaktionen!</p>
|
||||
<!-- Löschfunktion könnte hier hinzugefügt werden -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Konto bearbeiten - <%= typeof account !== 'undefined' ? account.name : 'Frühstückskonten' %></title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<% if (typeof account !== 'undefined' && account) { %>
|
||||
<h2>Konto bearbeiten: <%= account.name %></h2>
|
||||
|
||||
<form action="/accounts/<%= account.id %>", method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" value="<%= account.name %>", required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pin">Neue PIN (4-stellig, leer lassen zum Behalten):</label>
|
||||
<input type="password" id="pin" name="pin" pattern="\d{4}"
|
||||
title="Bitte genau 4 Ziffern eingeben" maxlength="4">
|
||||
</div>
|
||||
<button type="submit" class="btn">Speichern</button>
|
||||
<a href="/accounts/<%= account.id %>", class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<div class="danger-zone">
|
||||
<h4>Achtung: Kontolöschung</h4>
|
||||
<p>Das Löschen eines Kontos löscht auch alle zugehörigen Transaktionen!</p>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<p>Konto nicht gefunden.</p>
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,23 +1,59 @@
|
||||
<%- include('layout', { title: 'Neues Konto anlegen' }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Neues Konto anlegen</h2>
|
||||
|
||||
<form action="/accounts" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pin">PIN (4-stellig):</label>
|
||||
<input type="password" id="pin" name="pin" required pattern="\d{4}"
|
||||
title="Bitte genau 4 Ziffern eingeben" maxlength="4">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="initialBalance">Anfangsguthaben (€):</label>
|
||||
<input type="number" id="initialBalance" name="initialBalance" step="0.01" min="0" value="0.00">
|
||||
</div>
|
||||
<button type="submit" class="btn">Konto anlegen</button>
|
||||
<a href="/accounts" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
<% end %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Neues Konto anlegen - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<h2>Neues Konto anlegen</h2>
|
||||
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
|
||||
<form action="/accounts" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pin">PIN (4-stellig):</label>
|
||||
<input type="password" id="pin" name="pin" required pattern="\d{4}"
|
||||
title="Bitte genau 4 Ziffern eingeben" maxlength="4">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="initialBalance">Anfangsguthaben (€):</label>
|
||||
<input type="number" id="initialBalance" name="initialBalance" step="0.01" min="0" value="0.00">
|
||||
</div>
|
||||
<button type="submit" class="btn">Konto anlegen</button>
|
||||
<a href="/accounts" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,39 +1,77 @@
|
||||
<%- include('layout', { title: 'Konten' }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Kontenverwaltung</h2>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/accounts/new" class="btn">Neues Konto anlegen</a>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Konten - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<h2>Kontenverwaltung</h2>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/accounts/new" class="btn">Neues Konto anlegen</a>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Kontostand</th>
|
||||
<th>Erstellt am</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if (typeof accounts !== 'undefined' && accounts.length > 0) { %>
|
||||
<% accounts.forEach(function(account) { %>
|
||||
<tr>
|
||||
<td><%= account.name %></td>
|
||||
<td class="balance"><%= account.balance.toFixed(2) %> €</td>
|
||||
<td><%= new Date(account.created_at).toLocaleDateString('de-DE') %></td>
|
||||
<td>
|
||||
<a href="/accounts/<%= account.id %>">Details</a>
|
||||
| <a href="/accounts/<%= account.id %>/deposit">Einzahlen</a>
|
||||
| <a href="/accounts/<%= account.id %>/withdraw">Abbuchen</a>
|
||||
<% if (typeof isAdmin !== 'undefined' && isAdmin) { %>
|
||||
| <a href="/accounts/<%= account.id %>/edit">Bearbeiten</a>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
<% } else { %>
|
||||
<tr>
|
||||
<td colspan="4">Keine Konten vorhanden</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Gesamt: <%= typeof accounts !== 'undefined' ? accounts.length : 0 %> Konten</p>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Kontostand</th>
|
||||
<th>Erstellt am</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% accounts.forEach(account => { %>
|
||||
<tr>
|
||||
<td><%= account.name %></td>
|
||||
<td class="balance"><%= account.balance.toFixed(2) %> €</td>
|
||||
<td><%= new Date(account.created_at).toLocaleDateString('de-DE') %></td>
|
||||
<td>
|
||||
<a href="/accounts/<%= account.id %>">Details</a>
|
||||
| <a href="/accounts/<%= account.id %>/deposit">Einzahlen</a>
|
||||
| <a href="/accounts/<%= account.id %>/withdraw">Abbuchen</a>
|
||||
<% if (isAdmin) { %>
|
||||
| <a href="/accounts/<%= account.id %>/edit">Bearbeiten</a>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Gesamt: <%= accounts.length %> Konten</p>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,55 +1,93 @@
|
||||
<%- include('layout', { title: 'Dashboard' }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Dashboard</h2>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<div class="stat-card">
|
||||
<h3>Konten</h3>
|
||||
<p class="stat-value"><%= stats.count %></p>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h3>Gesamtguthaben</h3>
|
||||
<p class="stat-value"><%= (stats.total_balance || 0).toFixed(2) %> €</p>
|
||||
</div>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<h2>Dashboard</h2>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<div class="stat-card">
|
||||
<h3>Konten</h3>
|
||||
<p class="stat-value"><%= typeof stats !== 'undefined' ? stats.count : 0 %></p>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<h3>Gesamtguthaben</h3>
|
||||
<p class="stat-value"><%= typeof stats !== 'undefined' ? (stats.total_balance || 0).toFixed(2) : '0.00' %> €</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Letzte Transaktionen</h3>
|
||||
<table class="transaction-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Konto</th>
|
||||
<th>Typ</th>
|
||||
<th>Betrag</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Artikel</th>
|
||||
<th>Durchgeführt von</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if (typeof transactions !== 'undefined' && transactions.length > 0) { %>
|
||||
<% transactions.forEach(function(transaction) { %>
|
||||
<tr>
|
||||
<td><%= new Date(transaction.created_at).toLocaleString('de-DE') %></td>
|
||||
<td><%= transaction.account_name %></td>
|
||||
<td class="type-<%= transaction.type %>">
|
||||
<%= transaction.type === 'deposit' ? 'Einzahlung' : 'Abbuchung' %>
|
||||
</td>
|
||||
<td class="amount-<%= transaction.type %>">
|
||||
<%= transaction.amount.toFixed(2) %> €
|
||||
</td>
|
||||
<td><%= transaction.description %></td>
|
||||
<td><%= transaction.item_name || '-' %></td>
|
||||
<td><%= transaction.created_by_name || 'System' %></td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
<% } else { %>
|
||||
<tr>
|
||||
<td colspan="7">Keine Transaktionen vorhanden</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/accounts/new" class="btn">Neues Konto anlegen</a>
|
||||
<% if (typeof isAdmin !== 'undefined' && isAdmin) { %>
|
||||
<a href="/items/new" class="btn">Neuen Artikel anlegen</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<h3>Letzte Transaktionen</h3>
|
||||
<table class="transaction-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Konto</th>
|
||||
<th>Typ</th>
|
||||
<th>Betrag</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Artikel</th>
|
||||
<th>Durchgeführt von</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% transactions.forEach(transaction => { %>
|
||||
<tr>
|
||||
<td><%= new Date(transaction.created_at).toLocaleString('de-DE') %></td>
|
||||
<td><%= transaction.account_name %></td>
|
||||
<td class="type-<%= transaction.type %>">
|
||||
<%= transaction.type === 'deposit' ? 'Einzahlung' : 'Abbuchung' %>
|
||||
</td>
|
||||
<td class="amount-<%= transaction.type %>">
|
||||
<%= transaction.amount.toFixed(2) %> €
|
||||
</td>
|
||||
<td><%= transaction.description %></td>
|
||||
<td><%= transaction.item_name || '-' %></td>
|
||||
<td><%= transaction.created_by_name || 'System' %></td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/accounts/new" class="btn">Neues Konto anlegen</a>
|
||||
<% if (isAdmin) { %>
|
||||
<a href="/items/new" class="btn">Neuen Artikel anlegen</a>
|
||||
<% } %>
|
||||
</div>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,24 +1,56 @@
|
||||
<%- include('layout', { title: 'Geld einzahlen - ' + account.name }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Geld einzahlen für: <%= account.name %></h2>
|
||||
|
||||
<p>Aktueller Kontostand: <strong><%= account.balance.toFixed(2) %> €</strong></p>
|
||||
|
||||
<form action="/accounts/<%= account.id %>/deposit" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="amount">Betrag (€):</label>
|
||||
<input type="number" id="amount" name="amount" step="0.01" min="0.01" required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Beschreibung (optional):</label>
|
||||
<input type="text" id="description" name="description">
|
||||
</div>
|
||||
<button type="submit" class="btn">Einzahlen</button>
|
||||
<a href="/accounts/<%= account.id %>", class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<% if (error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
<% end %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Geld einzahlen - <%= typeof account !== 'undefined' ? account.name : 'Frühstückskonten' %></title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<% if (typeof account !== 'undefined' && account) { %>
|
||||
<h2>Geld einzahlen für: <%= account.name %></h2>
|
||||
|
||||
<p>Aktueller Kontostand: <strong><%= account.balance.toFixed(2) %> €</strong></p>
|
||||
|
||||
<form action="/accounts/<%= account.id %>/deposit" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="amount">Betrag (€):</label>
|
||||
<input type="number" id="amount" name="amount" step="0.01" min="0.01" required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Beschreibung (optional):</label>
|
||||
<input type="text" id="description" name="description">
|
||||
</div>
|
||||
<button type="submit" class="btn">Einzahlen</button>
|
||||
<a href="/accounts/<%= account.id %>", class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
<% } else { %>
|
||||
<p>Konto nicht gefunden.</p>
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,29 +1,65 @@
|
||||
<%- include('layout', { title: 'Artikel bearbeiten - ' + item.name }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Artikel bearbeiten: <%= item.name %></h2>
|
||||
|
||||
<form action="/items/<%= item.id %>", method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" required autofocus
|
||||
value="<%= item.name %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="price">Preis (€):</label>
|
||||
<input type="number" id="price" name="price" step="0.01" min="0.01" required
|
||||
value="<%= item.price.toFixed(2) %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Beschreibung (optional):</label>
|
||||
<input type="text" id="description" name="description"
|
||||
value="<%= item.description || '' %>">
|
||||
</div>
|
||||
<button type="submit" class="btn">Speichern</button>
|
||||
<a href="/items" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<% if (error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
<% end %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Artikel bearbeiten - <%= typeof item !== 'undefined' ? item.name : 'Frühstückskonten' %></title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<% if (typeof item !== 'undefined' && item) { %>
|
||||
<h2>Artikel bearbeiten: <%= item.name %></h2>
|
||||
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
|
||||
<form action="/items/<%= item.id %>", method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" required autofocus
|
||||
value="<%= item.name %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="price">Preis (€):</label>
|
||||
<input type="number" id="price" name="price" step="0.01" min="0.01" required
|
||||
value="<%= item.price.toFixed(2) %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Beschreibung (optional):</label>
|
||||
<input type="text" id="description" name="description"
|
||||
value="<%= item.description || '' %>">
|
||||
</div>
|
||||
<button type="submit" class="btn">Speichern</button>
|
||||
<a href="/items" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
<% } else { %>
|
||||
<p>Artikel nicht gefunden.</p>
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,29 +1,61 @@
|
||||
<%- include('layout', { title: 'Neuen Artikel anlegen' }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Neuen Artikel anlegen</h2>
|
||||
|
||||
<form action="/items" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" required autofocus
|
||||
value="<%= locals.name || '' %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="price">Preis (€):</label>
|
||||
<input type="number" id="price" name="price" step="0.01" min="0.01" required
|
||||
value="<%= locals.price || '' %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Beschreibung (optional):</label>
|
||||
<input type="text" id="description" name="description"
|
||||
value="<%= locals.description || '' %>">
|
||||
</div>
|
||||
<button type="submit" class="btn">Artikel anlegen</button>
|
||||
<a href="/items" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<% if (error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
<% end %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Neuen Artikel anlegen - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<h2>Neuen Artikel anlegen</h2>
|
||||
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
|
||||
<form action="/items" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" required autofocus
|
||||
value="<%= typeof name !== 'undefined' ? name : '' %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="price">Preis (€):</label>
|
||||
<input type="number" id="price" name="price" step="0.01" min="0.01" required
|
||||
value="<%= typeof price !== 'undefined' ? price : '' %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Beschreibung (optional):</label>
|
||||
<input type="text" id="description" name="description"
|
||||
value="<%= typeof description !== 'undefined' ? description : '' %>">
|
||||
</div>
|
||||
<button type="submit" class="btn">Artikel anlegen</button>
|
||||
<a href="/items" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
114
views/items.ejs
114
views/items.ejs
@ -1,39 +1,77 @@
|
||||
<%- include('layout', { title: 'Artikel' }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Artikelverwaltung</h2>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/items/new" class="btn">Neuen Artikel anlegen</a>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Artikel - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<h2>Artikelverwaltung</h2>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/items/new" class="btn">Neuen Artikel anlegen</a>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Preis</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if (typeof items !== 'undefined' && items.length > 0) { %>
|
||||
<% items.forEach(function(item) { %>
|
||||
<tr>
|
||||
<td><%= item.name %></td>
|
||||
<td><%= item.price.toFixed(2) %> €</td>
|
||||
<td><%= item.description || '-' %></td>
|
||||
<td>
|
||||
<a href="/items/<%= item.id %>/edit">Bearbeiten</a>
|
||||
|
|
||||
<form action="/items/<%= item.id %>/delete" method="POST" style="display: inline;">
|
||||
<button type="submit" class="btn-danger"
|
||||
onclick="return confirm('Artikel wirklich löschen?')">Löschen</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
<% } else { %>
|
||||
<tr>
|
||||
<td colspan="4">Keine Artikel vorhanden</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Gesamt: <%= typeof items !== 'undefined' ? items.length : 0 %> Artikel</p>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Preis</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% items.forEach(item => { %>
|
||||
<tr>
|
||||
<td><%= item.name %></td>
|
||||
<td><%= item.price.toFixed(2) %> €</td>
|
||||
<td><%= item.description || '-' %></td>
|
||||
<td>
|
||||
<a href="/items/<%= item.id %>/edit">Bearbeiten</a>
|
||||
|
|
||||
<form action="/items/<%= item.id %>/delete" method="POST" style="display: inline;">
|
||||
<button type="submit" class="btn-danger"
|
||||
onclick="return confirm('Artikel wirklich löschen?')">Löschen</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Gesamt: <%= items.length %> Artikel</p>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,26 +1,48 @@
|
||||
<%- include('layout', { title: 'Anmeldung' }) %>
|
||||
|
||||
<% override body %>
|
||||
<div class="login-container">
|
||||
<h2>Anmeldung</h2>
|
||||
<form action="/login" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="username">Benutzername:</label>
|
||||
<input type="text" id="username" name="username" required autofocus>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Anmeldung - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="login-container">
|
||||
<h2>Anmeldung</h2>
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
<form action="/login" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="username">Benutzername:</label>
|
||||
<input type="text" id="username" name="username" required autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Passwort:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit" class="btn">Anmelden</button>
|
||||
</form>
|
||||
<p class="login-hint">
|
||||
<strong>Standard-Anmeldung:</strong><br>
|
||||
Benutzername: admin<br>
|
||||
Passwort: admin123
|
||||
</p>
|
||||
<p class="pin-check-link">
|
||||
<a href="/pin-check">Kontostand mit PIN abfragen</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Passwort:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit" class="btn">Anmelden</button>
|
||||
</form>
|
||||
<p class="login-hint">
|
||||
<strong>Standard-Anmeldung:</strong><br>
|
||||
Benutzername: admin<br>
|
||||
Passwort: admin123
|
||||
</p>
|
||||
<p class="pin-check-link">
|
||||
<a href="/pin-check">Kontostand mit PIN abfragen</a>
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,29 +1,90 @@
|
||||
<%- include('layout', { title: 'Kontostand abfragen' }) %>
|
||||
|
||||
<% override body %>
|
||||
<div class="pin-check-container">
|
||||
<% if (!success) { %>
|
||||
<h2>Kontostand abfragen</h2>
|
||||
<p>Bitte geben Sie Ihre 4-stellige PIN ein, um Ihren Kontostand abzufragen.</p>
|
||||
|
||||
<form action="/pin-check" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="pin">PIN:</label>
|
||||
<input type="password" id="pin" name="pin" required autofocus
|
||||
pattern="\d{4}" title="Bitte genau 4 Ziffern eingeben" maxlength="4">
|
||||
</div>
|
||||
<button type="submit" class="btn">Kontostand abfragen</button>
|
||||
</form>
|
||||
|
||||
<p><a href="/login">Zur Mitarbeiter-Anmeldung</a></p>
|
||||
<% } else { %>
|
||||
<h2>Kontostand für <%= account.name %></h2>
|
||||
<div class="balance-display">
|
||||
<p>Ihr aktueller Kontostand beträgt:</p>
|
||||
<p class="balance-large"><%= account.balance.toFixed(2) %> €</p>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kontostand abfragen - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="pin-check-container">
|
||||
<% if (typeof success === 'undefined' || !success) { %>
|
||||
<h2>Kontostand abfragen</h2>
|
||||
<p>Bitte geben Sie Ihre 4-stellige PIN ein, um Ihren Kontostand und die letzten Buchungen abzufragen.</p>
|
||||
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
|
||||
<form action="/pin-check" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="pin">PIN:</label>
|
||||
<input type="password" id="pin" name="pin" required autofocus
|
||||
pattern="\d{4}" title="Bitte genau 4 Ziffern eingeben" maxlength="4">
|
||||
</div>
|
||||
<button type="submit" class="btn">Kontostand abfragen</button>
|
||||
</form>
|
||||
|
||||
<p><a href="/login">Zur Mitarbeiter-Anmeldung</a></p>
|
||||
<% } else { %>
|
||||
<h2>Kontostand für <%= typeof account !== 'undefined' ? account.name : 'Unbekannt' %></h2>
|
||||
|
||||
<div class="balance-display">
|
||||
<p>Ihr aktueller Kontostand beträgt:</p>
|
||||
<p class="balance-large"><%= typeof account !== 'undefined' ? account.balance.toFixed(2) : '0.00' %> €</p>
|
||||
</div>
|
||||
|
||||
<% if (typeof transactions !== 'undefined' && transactions.length > 0) { %>
|
||||
<h3>Letzte Buchungen:</h3>
|
||||
<table class="transaction-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Typ</th>
|
||||
<th>Betrag</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Artikel</th>
|
||||
<th>Durchgeführt von</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% transactions.forEach(function(transaction) { %>
|
||||
<tr>
|
||||
<td><%= new Date(transaction.created_at).toLocaleString('de-DE') %></td>
|
||||
<td class="type-<%= transaction.type %>">
|
||||
<%= transaction.type === 'deposit' ? 'Einzahlung' : 'Abbuchung' %>
|
||||
</td>
|
||||
<td class="amount-<%= transaction.type %>">
|
||||
<%= transaction.amount.toFixed(2) %> €
|
||||
</td>
|
||||
<td><%= transaction.description %></td>
|
||||
<td><%= transaction.item_name || '-' %></td>
|
||||
<td><%= transaction.created_by_name || 'System' %></td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% } else { %>
|
||||
<p>Keine Buchungen in den letzten 10 Transaktionen.</p>
|
||||
<% } %>
|
||||
|
||||
<div class="actions" style="margin-top: 20px;">
|
||||
<a href="/pin-check" class="btn">Neue Abfrage</a>
|
||||
<a href="/login" class="btn secondary">Zur Mitarbeiter-Anmeldung</a>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<p><a href="/pin-check" class="btn">Neue Abfrage</a></p>
|
||||
<p><a href="/login">Zur Mitarbeiter-Anmeldung</a></p>
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,30 +1,62 @@
|
||||
<%- include('layout', { title: 'Neuen Benutzer anlegen' }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Neuen Benutzer anlegen</h2>
|
||||
|
||||
<form action="/users" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="username">Benutzername:</label>
|
||||
<input type="text" id="username" name="username" required autofocus
|
||||
value="<%= locals.username || '' %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Passwort:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="role">Rolle:</label>
|
||||
<select id="role" name="role" required>
|
||||
<option value="employee" <%= locals.role === 'employee' ? 'selected' : '' %>>Mitarbeiter</option>
|
||||
<option value="admin" <%= locals.role === 'admin' ? 'selected' : '' %>>Administrator</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn">Benutzer anlegen</button>
|
||||
<a href="/users" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<% if (error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
<% end %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Neuen Benutzer anlegen - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<h2>Neuen Benutzer anlegen</h2>
|
||||
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
<div class="error"><%= error %></div>
|
||||
<% } %>
|
||||
|
||||
<form action="/users" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="username">Benutzername:</label>
|
||||
<input type="text" id="username" name="username" required autofocus
|
||||
value="<%= typeof username !== 'undefined' ? username : '' %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Passwort:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="role">Rolle:</label>
|
||||
<select id="role" name="role" required>
|
||||
<option value="employee" <%= typeof role !== 'undefined' && role === 'employee' ? 'selected' : '' %>>Mitarbeiter</option>
|
||||
<option value="admin" <%= typeof role !== 'undefined' && role === 'admin' ? 'selected' : '' %>>Administrator</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn">Benutzer anlegen</button>
|
||||
<a href="/users" class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
114
views/users.ejs
114
views/users.ejs
@ -1,39 +1,77 @@
|
||||
<%- include('layout', { title: 'Benutzerverwaltung' }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Benutzerverwaltung</h2>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/users/new" class="btn">Neuen Benutzer anlegen</a>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Benutzerverwaltung - Frühstückskonten Verwaltung</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<h2>Benutzerverwaltung</h2>
|
||||
|
||||
<div class="actions">
|
||||
<a href="/users/new" class="btn">Neuen Benutzer anlegen</a>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Benutzername</th>
|
||||
<th>Rolle</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if (typeof users !== 'undefined' && users.length > 0) { %>
|
||||
<% users.forEach(function(userItem) { %>
|
||||
<tr>
|
||||
<td><%= userItem.username %></td>
|
||||
<td><%= userItem.role %></td>
|
||||
<td>
|
||||
<% if (userItem.id !== user.id) { %>
|
||||
<form action="/users/<%= userItem.id %>/delete" method="POST" style="display: inline;">
|
||||
<button type="submit" class="btn-danger"
|
||||
onclick="return confirm('Benutzer wirklich löschen?')">Löschen</button>
|
||||
</form>
|
||||
<% } else { %>
|
||||
<span class="disabled">(Eigener Account)</span>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
<% } else { %>
|
||||
<tr>
|
||||
<td colspan="3">Keine Benutzer vorhanden</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Gesamt: <%= typeof users !== 'undefined' ? users.length : 0 %> Benutzer</p>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Benutzername</th>
|
||||
<th>Rolle</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% users.forEach(user => { %>
|
||||
<tr>
|
||||
<td><%= user.username %></td>
|
||||
<td><%= user.role %></td>
|
||||
<td>
|
||||
<% if (user.id !== currentUser.id) { %>
|
||||
<form action="/users/<%= user.id %>/delete" method="POST" style="display: inline;">
|
||||
<button type="submit" class="btn-danger"
|
||||
onclick="return confirm('Benutzer wirklich löschen?')">Löschen</button>
|
||||
</form>
|
||||
<% else %>
|
||||
<span class="disabled">(Eigener Account)</span>
|
||||
<% } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Gesamt: <%= users.length %> Benutzer</p>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,75 +1,113 @@
|
||||
<%- include('layout', { title: 'Betrag abbuchen - ' + account.name }) %>
|
||||
|
||||
<% override body %>
|
||||
<h2>Betrag abbuchen für: <%= account.name %></h2>
|
||||
|
||||
<p>Aktueller Kontostand: <strong><%= account.balance.toFixed(2) %> €</strong></p>
|
||||
|
||||
<% if (error) { %>
|
||||
<div class="error">
|
||||
<% if (error === 'insufficient_funds') { %>
|
||||
Nicht genügend Guthaben auf dem Konto!
|
||||
<% else if (error === 'invalid_amount') { %>
|
||||
Bitte einen gültigen Betrag eingeben!
|
||||
<% else if (error === 'invalid_item') { %>
|
||||
Ungültiger Artikel ausgewählt!
|
||||
<% else { %>
|
||||
<%= error %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Betrag abbuchen - <%= typeof account !== 'undefined' ? account.name : 'Frühstückskonten' %></title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Frühstückskonten Verwaltung</h1>
|
||||
<% if (typeof user !== 'undefined' && user) { %>
|
||||
<nav>
|
||||
<span>Angemeldet als: <strong><%= user.username %></strong> (<%= user.role %>) |
|
||||
<a href="/dashboard">Dashboard</a> |
|
||||
<a href="/accounts">Konten</a>
|
||||
<% if (user.role === 'admin') { %>
|
||||
| <a href="/items">Artikel</a>
|
||||
| <a href="/users">Benutzer</a>
|
||||
<% } %>
|
||||
| <a href="/logout">Abmelden</a>
|
||||
</span>
|
||||
</nav>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<form action="/accounts/<%= account.id %>/withdraw" method="POST">
|
||||
<div class="form-section">
|
||||
<h3>Option 1: Artikel auswählen</h3>
|
||||
<div class="form-group">
|
||||
<label for="itemId">Artikel:</label>
|
||||
<select id="itemId" name="itemId">
|
||||
<option value="">-- Artikel auswählen --</option>
|
||||
<% items.forEach(item => { %>
|
||||
<option value="<%= item.id %>">
|
||||
<%= item.name %> (<%= item.price.toFixed(2) %> €)
|
||||
<% if (item.description) { %>
|
||||
- <%= item.description %>
|
||||
<% } %>
|
||||
</option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Bemerkung (optional):</label>
|
||||
<input type="text" id="description" name="description">
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="form-section">
|
||||
<h3>Option 2: Manueller Betrag</h3>
|
||||
<div class="form-group">
|
||||
<label for="customAmount">Betrag (€):</label>
|
||||
<input type="number" id="customAmount" name="customAmount" step="0.01" min="0.01">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description2">Beschreibung (optional):</label>
|
||||
<input type="text" id="description2" name="description">
|
||||
</div>
|
||||
</div>
|
||||
<main>
|
||||
<% if (typeof account !== 'undefined' && account) { %>
|
||||
<h2>Betrag abbuchen für: <%= account.name %></h2>
|
||||
|
||||
<p>Aktueller Kontostand: <strong><%= account.balance.toFixed(2) %> €</strong></p>
|
||||
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
<div class="error">
|
||||
<% if (error === 'insufficient_funds') { %>
|
||||
Nicht genügend Guthaben auf dem Konto!
|
||||
<% } else if (error === 'invalid_amount') { %>
|
||||
Bitte einen gültigen Betrag eingeben!
|
||||
<% } else if (error === 'invalid_item') { %>
|
||||
Ungültiger Artikel ausgewählt!
|
||||
<% } else { %>
|
||||
<%= error %>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<form action="/accounts/<%= account.id %>/withdraw" method="POST">
|
||||
<div class="form-section">
|
||||
<h3>Option 1: Artikel auswählen</h3>
|
||||
<div class="form-group">
|
||||
<label for="itemId">Artikel:</label>
|
||||
<select id="itemId" name="itemId">
|
||||
<option value="">-- Artikel auswählen --</option>
|
||||
<% if (typeof items !== 'undefined' && items.length > 0) { %>
|
||||
<% items.forEach(function(item) { %>
|
||||
<option value="<%= item.id %>">
|
||||
<%= item.name %> (<%= item.price.toFixed(2) %> €)
|
||||
<% if (item.description) { %>
|
||||
- <%= item.description %>
|
||||
<% } %>
|
||||
</option>
|
||||
<% }); %>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Bemerkung (optional):</label>
|
||||
<input type="text" id="description" name="description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-section">
|
||||
<h3>Option 2: Manueller Betrag</h3>
|
||||
<div class="form-group">
|
||||
<label for="customAmount">Betrag (€):</label>
|
||||
<input type="number" id="customAmount" name="customAmount" step="0.01" min="0.01">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description2">Beschreibung (optional):</label>
|
||||
<input type="text" id="description2" name="description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn">Abbuchen</button>
|
||||
<a href="/accounts/<%= account.id %>", class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
// Ensure only one option is used at a time
|
||||
document.querySelector('select[name="itemId"]').addEventListener('change', function() {
|
||||
if (this.value) {
|
||||
document.getElementById('customAmount').value = '';
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('customAmount').addEventListener('input', function() {
|
||||
if (this.value) {
|
||||
document.querySelector('select[name="itemId"]').value = '';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<% } else { %>
|
||||
<p>Konto nicht gefunden.</p>
|
||||
<% } %>
|
||||
</main>
|
||||
|
||||
<button type="submit" class="btn">Abbuchen</button>
|
||||
<a href="/accounts/<%= account.id %>", class="btn secondary">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
// Ensure only one option is used at a time
|
||||
document.querySelector('select[name="itemId"]').addEventListener('change', function() {
|
||||
if (this.value) {
|
||||
document.getElementById('customAmount').value = '';
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('customAmount').addEventListener('input', function() {
|
||||
if (this.value) {
|
||||
document.querySelector('select[name="itemId"]').value = '';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
||||
<footer>
|
||||
<p>© 2024 Frühstückskonten Verwaltung</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user