Reporting-Funktionen, Admin-Funktion (neue User) und Installationshinweise

This commit is contained in:
fds2610 2026-01-19 18:21:21 +01:00
parent c20094a68a
commit 1f6126cc95
13 changed files with 279 additions and 104 deletions

View file

@ -4,17 +4,18 @@ Dokumentiere Ausgaben on-the-go als Webapp
V.1.1 (geplant)
Als nächstes kommen Auswertungen / Summen
Admin-Funktion:
- in der config.php kann vorkonfiguriert werden, welchen User_ids erlaubt ist, weitere User anzulegen.
Auswertungen:
- [X] Monatssumme je Kategorie
- [ ] Filter monatsweise
- [ ] monate durchblättern zurück und vor, defaut aktueller Monat
- [X] Filter monatsweise
- [X] monate durchblättern zurück und vor, defaut aktueller Monat
- [X] Monatssumme je Person
- [ ] Haken, welche Kategorieen eingeschlossen werden
- [ ] Filter monatssummen
- [ ] monate durchblättern zurück und vor, defaut aktueller Monat
- [X] Haken, welche Kategorieen eingeschlossen werden
- [X] Filter monatssummen
- [X] monate durchblättern zurück und vor, defaut aktueller Monat
V.1.0
@ -65,3 +66,14 @@ Weiteres
- [x] Betrag deutsche Zahlen und rechtsbündig
- [x] Kommentarfeld freitext drei Zeilen
Installationshinweise:
1. webserver & DB server aufsetzen
2. init.sql script als berechtigter DB user laufen lassen (meist root), der Datenbanken anlegen und Berechtigungen setzen kann.
3. html Ordner ins webroot kopieren
4. config_sample.php in config.php umbenennen und DB credentials setzen
5. webroot (z.B. http://localhost/) aufrufen und mit user test / test123 einloggen.
6. obige Schritte sind nur das Nötigste, um die Funktionalität herzustellen. Insbesondere bei Zugriffsmöglichkeiten aus dem Internet ist es wichtig, https Protokolle, vpns und/oder ggfs zusätzliche Sicherungsmassnahmen (hardening) zu ergreifen.
Das sollte alles sein. Bitte erstellt ein Bug-Ticket, wenn ich etwas übersehen habe. Gerne könnt Ihr auch Pull-Requests erstellen.

View file

@ -0,0 +1,3 @@
[Trash Info]
Path=new_entry_old.php
DeletionDate=2026-01-19T16:16:39

View file

@ -1,6 +1,13 @@
<?php
// Datenbankverbindung
require 'config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: index.php');
exit;
}
echo $_SESSION['user_id'];
error_log($_SESSION['user_id']);
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
@ -35,7 +42,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin: Benutzer anlegen</title>
<title>A L T ! ! ! Admin: Benutzer anlegen</title>
<style>
body { font-family: Arial, sans-serif; max-width: 500px; margin: 0 auto; padding: 20px; }
.form-group { margin-bottom: 15px; }

View file

@ -68,6 +68,10 @@ h1 {
outline: none;
}
#categories_rep_person {
font-size: 12px;
}
.btn-submit {
display: inline-block;
background: var(--primary-color);
@ -93,13 +97,21 @@ h1 {
.nav {
display: flex;
align-items: center;
justify-content: space-between;
justify-content: flex-start;
padding: 10px 20px;
background: var(--primary-color);
border-radius: var(--border-radius);
margin-bottom: 20px;
}
.nav-list {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
.hamburger {
display: none;
background: rgba(255, 255, 255, 0.2);
@ -118,12 +130,6 @@ h1 {
background: rgba(255, 255, 255, 0.3);
}
.nav-list {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
.nav-list li {
margin: 0 5px;
@ -143,6 +149,25 @@ h1 {
background: rgba(255, 255, 255, 0.25);
}
/* Allgemeine Navigation-Button-Stile */
.nav-button {
color: white;
text-decoration: none;
font-size: 1rem;
font-weight: 500;
padding: 8px 12px;
border-radius: var(--border-radius);
background: rgba(255, 255, 255, 0.2);
transition: var(--transition);
margin-right: 10px; /* Abstand zum nächsten Button */
}
/* Hover-Effekte für die Navigation-Buttons */
.nav-button:hover {
background: rgba(255, 255, 255, 0.3);
}
/* Logout Button */
.logout {
color: white;
text-decoration: none;
@ -152,8 +177,10 @@ h1 {
border-radius: var(--border-radius);
background: rgba(255, 255, 255, 0.2);
transition: var(--transition);
margin-left: 10px; /* Abstand von den anderen Buttons */
}
/* Hover-Effekte für Logout Button */
.logout:hover {
background: rgba(255, 255, 255, 0.3);
}

View file

@ -1,11 +1,19 @@
<?php
session_start();
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 0); // Nur 1, wenn du HTTPS verwendest!
ini_set('session.cookie_samesite', 'Lax');
$host = 'localhost';
$db = 'finanzapp';
$user = 'user'; // Anpassen!
$pass = 'password'; // Anpassen!
$charset = 'utf8mb4';
$selectedCategories = [1, 2, 3]; // Anpassen! Dies sind die Standard-Ketegorien die für rep_person als default angenommen werden.
$admin_ids = [1,2];
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,

View file

@ -1,23 +1,20 @@
<?php
require 'config.php';
//if (!isset($_SESSION['user_id'])) {
// header('Location: index.php');
// exit;
//}
// echo $_SESSION['user_id'];
error_log($_SESSION['user_id']);
// Login-Logik
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_POST['username']]);
$user = $stmt->fetch();
if ($user && password_verify($_POST['password'], $user['password'])) {
$_SESSION['user_id'] = $user['id'];
} else {
error_log('Session user_id: ' . (isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 'nicht gesetzt'));
// 1. Session-Prüfung (nur für geschützte Seiten)
if (!isset($_SESSION['user_id'])) {
header('Location: index.php');
exit;
}
// Ab hier: Nur für angemeldete Benutzer
error_log($_SESSION['user_id']);
// Standard: kein Admin
$is_admin = "false";
// Prüfen, ob die user_id im Admin-Array ist
if (in_array($_SESSION['user_id'], $admin_ids, true)) {
$is_admin = "true";
}
// Daten abrufen
@ -71,7 +68,7 @@ $entries = $stmt->fetchAll();
<button class="hamburger">☰</button>
<ul class="nav-list">
<li><a href="dashboard.php">Start</a></li>
<li><a href="register.php">Neue User</a></li>
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
<li><a href="rep-month.php">Report Monat</a></li>
<li><a href="rep-person.php">Report Personen</a></li>
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>

View file

@ -1,9 +1,28 @@
<?php
require 'config.php';
// Falls bereits angemeldet, direkt zum Dashboard
if (isset($_SESSION['user_id'])) {
header('Location: dashboard.php');
exit;
}
// Login-Logik
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_POST['username']]);
$user = $stmt->fetch();
if ($user && password_verify($_POST['password'], $user['password'])) {
$_SESSION['user_id'] = $user['id'];
error_log('User-ID nach Login: ' . $_SESSION['user_id']);
header('Location: dashboard.php');
exit;
} else {
$error = "Benutzername oder Passwort falsch!";
}
}
?>
<!DOCTYPE html>
<html lang="de">
@ -28,7 +47,10 @@ Mit der weiteren Nutzung der Webseite erklären Sie sich mit dem Einsatz dieser
<div class="modal-content">
<img src="assets/img/euro.gif"/>
<h2>FSCash</h2>
<form action="dashboard.php" method="post">
<?php if ($error): ?>
<p class="error"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>
<form action="index.php" method="post">
<input type="text" name="username" placeholder="Benutzername" required>
<input type="password" name="password" placeholder="Passwort" required>
<button type="submit">Einloggen</button>

41
html/index_old.php Normal file
View file

@ -0,0 +1,41 @@
<?php
require 'config.php';
if (isset($_SESSION['user_id'])) {
header('Location: dashboard.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FSCash - Login</title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<!-- Cookie-Hinweis -->
<div id="cookie-notice" class="cookie-notice">
<p>
Cookie-Hinweis:<br/>
Auf dieser Webseite werden nur technisch notwendige Cookies verwendet, die nach dem Logout automatisch gelöscht werden. <br/>
Mit der weiteren Nutzung der Webseite erklären Sie sich mit dem Einsatz dieser Technologie einverstanden.
</p>
</div>
<!-- Modal Login Dialog -->
<div id="login-modal" class="modal">
<div class="modal-content">
<img src="assets/img/euro.gif"/>
<h2>FSCash</h2>
<form action="dashboard.php" method="post">
<input type="text" name="username" placeholder="Benutzername" required>
<input type="password" name="password" placeholder="Passwort" required>
<button type="submit">Einloggen</button>
</form>
</div>
</div>
<script src="assets/js/script.js"></script>
</body>
</html>

View file

@ -124,9 +124,9 @@ Daten gespeichert !
<button class="hamburger">☰</button>
<ul class="nav-list">
<li><a href="dashboard.php">Start</a></li>
<li><a href="register.php">Neue User</a></li>
<li><a href="menu3.php" style="display: none;">Menüpunkt 3</a></li>
<li><a href="menu4.php" style="display: none;">Menüpunkt 4</a></li>
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
<li><a href="rep-month.php">Report Monat</a></li>
<li><a href="rep-person.php">Report Personen</a></li>
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
</ul>
<a href="logout.php" class="logout">Logout</a>

View file

@ -1,6 +1,12 @@
<?php
// register.php
require 'config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: index.php');
exit;
}
// echo $_SESSION['user_id'];
error_log($_SESSION['user_id']);
// Verbindung herstellen
@ -47,9 +53,9 @@ $conn->close();
<button class="hamburger">☰</button>
<ul class="nav-list">
<li><a href="dashboard.php">Start</a></li>
<li><a href="register.php">Neue User</a></li>
<li><a href="menu3.php" style="display: none;">Menüpunkt 3</a></li>
<li><a href="menu4.php" style="display: none;">Menüpunkt 4</a></li>
<li><a href="register.php" style="display: none;">Neue User</a></li>
<li><a href="rep-month.php">Report Monat</a></li>
<li><a href="rep-person.php">Report Personen</a></li>
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
</ul>
<a href="logout.php" class="logout">Logout</a>

View file

@ -1,52 +1,56 @@
<?php
require 'config.php';
//if (!isset($_SESSION['user_id'])) {
// header('Location: index.php');
// exit;
//}
// echo $_SESSION['user_id'];
error_log($_SESSION['user_id']);
// Login-Logik
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_POST['username']]);
$user = $stmt->fetch();
if ($user && password_verify($_POST['password'], $user['password'])) {
$_SESSION['user_id'] = $user['id'];
} else {
if (!isset($_SESSION['user_id'])) {
header('Location: index.php');
exit;
}
// Aktuelles Jahr und Monat ermitteln, ggf. aus GET-Parametern
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
$month = isset($_GET['month']) ? (int)$_GET['month'] : (int)date('m');
// Monats- und Jahresgrenzen prüfen und anpassen
if ($month < 1) {
$month = 12;
$year--;
} elseif ($month > 12) {
$month = 1;
$year++;
}
// Daten abrufen
$sql="SELECT
// Daten abrufen für den ausgewählten Monat
$sql = "
SELECT
c.category_id AS kategorie_id,
c.name AS kategorie_name,
SUM(e.amount) AS summe_je_kategorie
COALESCE(SUM(e.amount), 0) AS summe_je_kategorie
FROM
categories c
LEFT JOIN
entries e
LEFT JOIN categories c ON e.category = c.category_id
WHERE
EXTRACT(YEAR FROM e.date) = EXTRACT(YEAR FROM CURRENT_DATE())
AND EXTRACT(MONTH FROM e.date) = EXTRACT(MONTH FROM CURRENT_DATE())
ON e.category = c.category_id
AND EXTRACT(YEAR FROM e.date) = :year
AND EXTRACT(MONTH FROM e.date) = :month
GROUP BY
c.category_id, c.name
ORDER BY
c.category_id ASC;
c.category_id ASC
";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$stmt->execute([
'year' => $year,
'month' => $month
]);
$entries = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=0.8">
<title>FSCash - Dashboard</title>
<title>FSCash - Monatsreport</title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
@ -56,14 +60,20 @@ $entries = $stmt->fetchAll();
<button class="hamburger">☰</button>
<ul class="nav-list">
<li><a href="dashboard.php">Start</a></li>
<li><a href="register.php">Neue User</a></li>
<li><a href="rep-month.php">Report Monat</a></li>
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
<li><a href="rep-person.php">Report Personen</a></li>
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
</ul>
<!-- Container für die rechten Buttons -->
<div class="nav-right">
<a href="?year=<?= $year ?>&month=<?= $month - 1 ?>" class="nav-button"> &lt; </a>
<a href="?year=<?= $year ?>&month=<?= $month + 1 ?>" class="nav-button"> &gt; </a>
<a href="logout.php" class="logout">Logout</a>
</div>
</nav>
<h2><?= strftime('%B %Y', mktime(0, 0, 0, $month, 1, $year)) ?></h2>
<table class="thin">
<thead>
<tr>
@ -83,8 +93,6 @@ $entries = $stmt->fetchAll();
</tbody>
</table>
<!-- Neu-Button -->
<a href="new_entry.php" class="btn-xr">+</a>
</div>

View file

@ -1,39 +1,55 @@
<?php
require 'config.php';
//if (!isset($_SESSION['user_id'])) {
// header('Location: index.php');
// exit;
//}
// echo $_SESSION['user_id'];
error_log($_SESSION['user_id']);
// Login-Logik
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_POST['username']]);
$user = $stmt->fetch();
if ($user && password_verify($_POST['password'], $user['password'])) {
$_SESSION['user_id'] = $user['id'];
} else {
if (!isset($_SESSION['user_id'])) {
header('Location: index.php');
exit;
}
// Aktuelles Jahr und Monat ermitteln, ggf. aus GET-Parametern
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
$month = isset($_GET['month']) ? (int)$_GET['month'] : (int)date('m');
// Monats- und Jahresgrenzen prüfen und anpassen
if ($month < 1) {
$month = 12;
$year--;
} elseif ($month > 12) {
$month = 1;
$year++;
}
// Daten abrufen
$sql="SELECT
// Kategorien aus der Datenbank abrufen
$categoryStmt = $pdo->query("SELECT category_id, name FROM categories ORDER BY name");
$categories = $categoryStmt->fetchAll();
// Standardmäßig alle Kategorien auswählen, falls keine Auswahl getroffen wurde
// $selectedCategories = isset($_GET['categories']) ? $_GET['categories'] : array_column($categories, 'category_id');
if (array_key_exists('categories', $_GET) && $_GET['categories'] !== []) {
$selectedCategories = $_GET['categories'];
}
// Daten abrufen für den ausgewählten Monat und die ausgewählten Kategorien
$sql = "
SELECT
u.id AS user_id,
u.username,
COALESCE(SUM(e.amount), 0) AS gesamtbetrag
FROM users u
LEFT JOIN entries e ON e.user_id = u.id
WHERE MONTH(e.date) = MONTH(CURDATE())
AND YEAR(e.date) = YEAR(CURDATE())
GROUP BY u.id, u.username;
FROM
users u
LEFT JOIN
entries e ON e.user_id = u.id
AND MONTH(e.date) = ?
AND YEAR(e.date) = ?
AND e.category IN (" . implode(',', array_fill(0, count($selectedCategories), '?')) . ")
GROUP BY
u.id, u.username;
";
$params = array_merge([$month, $year], $selectedCategories);
$stmt = $pdo->prepare($sql);
$stmt->execute();
$stmt->execute($params);
$entries = $stmt->fetchAll();
?>
<!DOCTYPE html>
@ -41,7 +57,7 @@ $entries = $stmt->fetchAll();
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=0.8">
<title>FSCash - Dashboard</title>
<title>FSCash - Personenreport</title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
@ -51,14 +67,44 @@ $entries = $stmt->fetchAll();
<button class="hamburger">☰</button>
<ul class="nav-list">
<li><a href="dashboard.php">Start</a></li>
<li><a href="register.php">Neue User</a></li>
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
<li><a href="rep-month.php">Report Monat</a></li>
<li><a href="rep-person.php">Report Personen</a></li>
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
</ul>
<!-- Container für die rechten Buttons -->
<div class="nav-right">
<a href="?year=<?= $year ?>&month=<?= $month - 1 ?>" class="nav-button"> &lt; </a>
<a href="?year=<?= $year ?>&month=<?= $month + 1 ?>" class="nav-button"> &gt; </a>
<a href="logout.php" class="logout">Logout</a>
</div>
</nav>
<h2><?= strftime('%B %Y', mktime(0, 0, 0, $month, 1, $year)) ?></h2>
<!-- Multiselect für Kategorien -->
<form method="get" action="rep-person.php" class="category-filter">
<input type="hidden" name="year" value="<?= $year ?>">
<input type="hidden" name="month" value="<?= $month ?>">
<label for="categories">Kategorien:</label>
<div class="category-checkbox-list" id="categories_rep_person">
<?php foreach ($categories as $category): ?>
<label class="category-checkbox">
<input
type="checkbox"
name="categories[]"
value="<?= $category['category_id'] ?>"
<?= in_array($category['category_id'], $selectedCategories) ? 'checked' : '' ?>
onchange="this.form.submit()"
>
<?= htmlspecialchars($category['name']) ?>
</label><br/>
<?php endforeach; ?>
<br/></div>
<!-- button type="submit">Filtern</button -->
</form>
<table class="thin">
<thead>
<tr>
@ -76,8 +122,6 @@ $entries = $stmt->fetchAll();
</tbody>
</table>
<script>
// Hamburger-Menü-Funktion
document.querySelector('.hamburger').addEventListener('click', function() {