This commit is contained in:
commit
b294ceeec8
18
config/config.php
Normal file
18
config/config.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'host' => '127.0.0.1',
|
||||||
|
'dbname' => 'vwl',
|
||||||
|
'user' => 'root',
|
||||||
|
'password' => '',
|
||||||
|
'charset' => 'utf8mb4'
|
||||||
|
];
|
||||||
|
/*
|
||||||
|
return [
|
||||||
|
'host' => '148.251.96.181',
|
||||||
|
'dbname' => 'c1vwl',
|
||||||
|
'user' => 'c1gutscheinserver',
|
||||||
|
'password' => 'SommerNacht!2025',
|
||||||
|
'charset' => 'utf8mb4'
|
||||||
|
];
|
||||||
|
*/
|
||||||
23
core/App.php
Normal file
23
core/App.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class App {
|
||||||
|
|
||||||
|
protected $controller = 'MainController';
|
||||||
|
protected $method = 'home';
|
||||||
|
protected $params = [];
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
if (isset($_GET['page'])) {
|
||||||
|
$this->method = $_GET['page'];
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once '../src/controller/' . $this->controller . '.php';
|
||||||
|
$this->controller = new $this->controller;
|
||||||
|
|
||||||
|
if (!method_exists($this->controller, $this->method)) {
|
||||||
|
$this->method = 'home';
|
||||||
|
}
|
||||||
|
|
||||||
|
call_user_func_array([$this->controller, $this->method], $this->params);
|
||||||
|
}
|
||||||
|
}
|
||||||
26
core/Database.php
Normal file
26
core/Database.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Database
|
||||||
|
{
|
||||||
|
private static ?PDO $pdo = null;
|
||||||
|
|
||||||
|
public static function connect(): PDO
|
||||||
|
{
|
||||||
|
if (self::$pdo === null) {
|
||||||
|
$config = require __DIR__ . '/../config/config.php';
|
||||||
|
|
||||||
|
$dsn = "mysql:host={$config['host']};dbname={$config['dbname']};charset={$config['charset']}";
|
||||||
|
|
||||||
|
try {
|
||||||
|
self::$pdo = new PDO($dsn, $config['user'], $config['password'], [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
|
||||||
|
]);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
die("Datenbankverbindung fehlgeschlagen: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$pdo;
|
||||||
|
}
|
||||||
|
}
|
||||||
58
core/Request.php
Normal file
58
core/Request.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Request {
|
||||||
|
|
||||||
|
public static function post(string $key, mixed $default = null): mixed {
|
||||||
|
return $_POST[$key] ?? $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get(string $key, mixed $default = null): mixed {
|
||||||
|
return $_GET[$key] ?? $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function hasPost(string $key): bool {
|
||||||
|
return isset($_POST[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function hasGet(string $key): bool {
|
||||||
|
return isset($_GET[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function allPost(): array {
|
||||||
|
return $_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function allGet(): array {
|
||||||
|
return $_GET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: Sanitize input
|
||||||
|
public static function postSanitized(string $key, mixed $default = null): mixed {
|
||||||
|
return htmlspecialchars($_POST[$key] ?? $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: Boolean inputs (z. B. Checkbox, Radio, etc.)
|
||||||
|
public static function postBool(string $key): bool {
|
||||||
|
return isset($_POST[$key]) && ($_POST[$key] === '1' || $_POST[$key] === 'true' || $_POST[$key] === 'on');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function server(string $key, mixed $default = null): mixed {
|
||||||
|
return $_SERVER[$key] ?? $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isPost(): bool {
|
||||||
|
return self::server('REQUEST_METHOD') === 'POST';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isGet(): bool {
|
||||||
|
return self::server('REQUEST_METHOD') === 'GET';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function clientIp(): string {
|
||||||
|
return self::server('REMOTE_ADDR', '0.0.0.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function userAgent(): string {
|
||||||
|
return self::server('HTTP_USER_AGENT', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
7
nbproject/project.properties
Normal file
7
nbproject/project.properties
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
include.path=${php.global.include.path}
|
||||||
|
php.version=PHP_82
|
||||||
|
source.encoding=UTF-8
|
||||||
|
src.dir=.
|
||||||
|
tags.asp=false
|
||||||
|
tags.short=false
|
||||||
|
web.root=.
|
||||||
9
nbproject/project.xml
Normal file
9
nbproject/project.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>org.netbeans.modules.php.project</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/php-project/1">
|
||||||
|
<name>vwlsupport</name>
|
||||||
|
</data>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
||||||
25
src/controller/MainController.php
Normal file
25
src/controller/MainController.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class MainController {
|
||||||
|
|
||||||
|
public function home() {
|
||||||
|
$pageTitle = "Home";
|
||||||
|
require '../src/view/templates/header.php';
|
||||||
|
require '../src/view/home.php';
|
||||||
|
require '../src/view/templates/footer.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hotels() {
|
||||||
|
$pageTitle = "Hotels";
|
||||||
|
require '../src/view/templates/header.php';
|
||||||
|
require '../src/view/hotels.php';
|
||||||
|
require '../src/view/templates/footer.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hotel_edit() {
|
||||||
|
$pageTitle = "Hotel bearbeiten";
|
||||||
|
require '../src/view/templates/header.php';
|
||||||
|
require '../src/view/hotel_edit.php';
|
||||||
|
require '../src/view/templates/footer.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
74
src/model/AnschriftModel.php
Normal file
74
src/model/AnschriftModel.php
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../core/Database.php';
|
||||||
|
|
||||||
|
class AnschriftModel {
|
||||||
|
|
||||||
|
private PDO $db;
|
||||||
|
|
||||||
|
private array $dbFields = [
|
||||||
|
'land', 'plz', 'ort', 'strasse', 'ansprechpartner',
|
||||||
|
'telefon', 'email'
|
||||||
|
];
|
||||||
|
|
||||||
|
private array $frmFields;
|
||||||
|
private array $rgFrmFields = [
|
||||||
|
'rg_land', 'rg_plz', 'rg_ort', 'rg_strasse', 'rg_ansprechpartner',
|
||||||
|
'rg_telefon', 'rg_email'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->db = Database::connect();
|
||||||
|
$this->frmFields = $this->dbFields; // Standard-Feldmapping
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findById($id): ?array {
|
||||||
|
$stmt = $this->db->prepare("SELECT * FROM vwl_anschrift WHERE id = :id");
|
||||||
|
$stmt->execute(['id' => $id]);
|
||||||
|
return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, $formData, $rgAnschrift = false) {
|
||||||
|
$formFields = $rgAnschrift ? $this->rgFrmFields : $this->frmFields;
|
||||||
|
$data = $this->mapFormToDbFields($formData, $formFields);
|
||||||
|
|
||||||
|
if (empty($data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($id)) {
|
||||||
|
return $this->insertData($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->updateData($id, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function insertData(array $data): int {
|
||||||
|
$fields = array_keys($data);
|
||||||
|
$placeholders = array_map(fn($f) => ":$f", $fields);
|
||||||
|
$sql = "INSERT INTO vwl_anschrift (" . implode(', ', $fields) . ") VALUES (" . implode(', ', $placeholders) . ")";
|
||||||
|
$stmt = $this->db->prepare($sql);
|
||||||
|
$stmt->execute($data);
|
||||||
|
return (int)$this->db->lastInsertId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateData($id, array $data): int {
|
||||||
|
$assignments = array_map(fn($f) => "$f = :$f", array_keys($data));
|
||||||
|
$sql = "UPDATE vwl_anschrift SET " . implode(', ', $assignments) . " WHERE id = :id";
|
||||||
|
$stmt = $this->db->prepare($sql);
|
||||||
|
$data['id'] = $id;
|
||||||
|
$stmt->execute($data);
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function mapFormToDbFields(array $formData, array $formFields): array {
|
||||||
|
$mapped = [];
|
||||||
|
foreach ($this->dbFields as $i => $dbField) {
|
||||||
|
$formField = $formFields[$i] ?? null;
|
||||||
|
if ($formField && isset($formData[$formField])) {
|
||||||
|
$mapped[$dbField] = $formData[$formField];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $mapped;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/model/BankverbindungModel.php
Normal file
33
src/model/BankverbindungModel.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../../core/Database.php';
|
||||||
|
|
||||||
|
class BankverbindungModel
|
||||||
|
{
|
||||||
|
public static function findById($id)
|
||||||
|
{
|
||||||
|
$pdo = Database::connect();
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM vwl_bankverbindung WHERE id = :id");
|
||||||
|
$stmt->execute(['id' => $id]);
|
||||||
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function update($id, $data)
|
||||||
|
{
|
||||||
|
$pdo = Database::connect();
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE vwl_bankverbindung SET
|
||||||
|
bank = :bank,
|
||||||
|
iban = :iban,
|
||||||
|
bic = :bic,
|
||||||
|
inhaber = :inhaber
|
||||||
|
WHERE id = :id
|
||||||
|
");
|
||||||
|
$stmt->execute([
|
||||||
|
'bank' => $data['bank'],
|
||||||
|
'iban' => $data['iban'],
|
||||||
|
'bic' => $data['bic'],
|
||||||
|
'inhaber' => $data['inhaber'],
|
||||||
|
'id' => $data['bankid']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
131
src/model/HotelModel.php
Normal file
131
src/model/HotelModel.php
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../core/Database.php';
|
||||||
|
require_once 'AnschriftModel.php';
|
||||||
|
require_once 'BankverbindungModel.php';
|
||||||
|
|
||||||
|
class HotelModel {
|
||||||
|
|
||||||
|
private PDO $db;
|
||||||
|
private AnschriftModel $mdlAnschr;
|
||||||
|
|
||||||
|
private $allowedFields = [
|
||||||
|
'hotelname', 'hotelnummer', 'provsatz', 'rg_hotelname', 'rg_interval',
|
||||||
|
'rg_vondatum', 'rg_bisdatum', 'rg_laufdatum', 'rg_ustid', 'rg_ustfrei',
|
||||||
|
'rg_provmode', 'status', 'notiz', 'intern', 'frueherechnung',
|
||||||
|
'passwort', 'loginname', 'nichtanzeigen', 'anschriftid', 'rg_anschriftid',
|
||||||
|
'bankid', 'rg_bankid', 'betreuer'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->db = Database::connect();
|
||||||
|
$this->mdlAnschr = new AnschriftModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHotelById($id) {
|
||||||
|
$stmt = $this->db->prepare("SELECT * FROM vwl_hotel WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
return $stmt->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAnschriftById($id) {
|
||||||
|
$stmt = $this->db->prepare("SELECT * FROM vwl_anschrift WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
return $stmt->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBankverbindungById($id) {
|
||||||
|
$stmt = $this->db->prepare("SELECT * FROM vwl_bankverbindung WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
return $stmt->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateHotel($data) {
|
||||||
|
|
||||||
|
$fieldsToUpdate = array_intersect_key($data, array_flip($this->allowedFields));
|
||||||
|
if (empty($fieldsToUpdate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baue SQL-Statement
|
||||||
|
$setParts = [];
|
||||||
|
foreach ($fieldsToUpdate as $field => $value) {
|
||||||
|
$setParts[] = "`$field` = :$field";
|
||||||
|
}
|
||||||
|
$sql = "UPDATE vwl_hotel SET " . implode(', ', $setParts) . " WHERE id = :id";
|
||||||
|
|
||||||
|
$stmt = $this->db->prepare($sql);
|
||||||
|
|
||||||
|
// Bind-Werte
|
||||||
|
$fieldsToUpdate['id'] = $data['id'];
|
||||||
|
return $stmt->execute($fieldsToUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findByIdWithRelations($id) {
|
||||||
|
$stmt = $this->db->prepare("
|
||||||
|
SELECT * FROM vwl_hotel WHERE id = :id
|
||||||
|
");
|
||||||
|
$stmt->execute(['id' => $id]);
|
||||||
|
$hotel = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($hotel) {
|
||||||
|
$hotel['anschrift'] = $this->mdlAnschr->findById($hotel['anschriftid']);
|
||||||
|
$hotel['bankverbindung'] = BankverbindungModel::findById($hotel['bankid']);
|
||||||
|
$hotel['rg_anschrift'] = $this->mdlAnschr->findById($hotel['rg_anschriftid']);
|
||||||
|
$hotel['rg_bankverbindung'] = BankverbindungModel::findById($hotel['rg_bankid']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hotel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRechnungen($id) {
|
||||||
|
$stmt = $this->db->prepare("
|
||||||
|
SELECT r.*, h.hotelnummer
|
||||||
|
FROM vwl_hotel_rechnung r
|
||||||
|
JOIN vwl_hotel h ON r.hotelid = h.id
|
||||||
|
WHERE h.id = :hotelid
|
||||||
|
ORDER BY r.rechnungsdatum DESC
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute(['hotelid' => $id]);
|
||||||
|
$stmt->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateWithRelations($id, $data) {
|
||||||
|
$this->db->beginTransaction();
|
||||||
|
try {
|
||||||
|
// 1. Anschrift aktualisieren
|
||||||
|
|
||||||
|
$subid = $this->mdlAnschr->update($data['anschriftid'], $data, false);
|
||||||
|
if(empty($subid) == false) {
|
||||||
|
$data['anschriftid'] = $subid;
|
||||||
|
}
|
||||||
|
// 1.1 Rechungsanschrift aktualisieren
|
||||||
|
$subidRg = $this->mdlAnschr->update($data['rg_anschriftid'], $data, true);
|
||||||
|
if(empty($subidRg) == false) {
|
||||||
|
$data['rg_anschriftid'] = $subidRg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Bankverbindung aktualisieren
|
||||||
|
BankverbindungModel::update($data['bankid'], $data);
|
||||||
|
|
||||||
|
// 3. Hotel aktualisieren
|
||||||
|
$fieldsToUpdate = array_intersect_key($data, array_flip($this->allowedFields));
|
||||||
|
if (empty($fieldsToUpdate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->updateHotel($data);
|
||||||
|
|
||||||
|
$this->db->commit();
|
||||||
|
return true;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->db->rollBack();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
2
src/view/home.php
Normal file
2
src/view/home.php
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h4>Startseite</h4>
|
||||||
|
<p>Willkommen auf der Startseite deiner Anwendung!</p>
|
||||||
83
src/view/hotel_edit.php
Normal file
83
src/view/hotel_edit.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../core/Request.php';
|
||||||
|
require_once '../src/model/HotelModel.php';
|
||||||
|
|
||||||
|
$hotelId = Request::get('id');
|
||||||
|
$message = '';
|
||||||
|
$hotelModel = new HotelModel();
|
||||||
|
|
||||||
|
// POST-Verarbeitung
|
||||||
|
if (Request::isPost()) {
|
||||||
|
$data = Request::allPost();
|
||||||
|
|
||||||
|
// ID-Felder ausblenden, aber für Speicherung mitgeben
|
||||||
|
$data['anschriftid'] = Request::post('anschriftid') ?? null;
|
||||||
|
$data['rg_anschriftid'] = Request::post('rg_anschriftid') ?? null;
|
||||||
|
$data['bankid'] = Request::post('bankid') ?? null;
|
||||||
|
|
||||||
|
$success = $hotelModel->updateWithRelations($hotelId, $data);
|
||||||
|
|
||||||
|
if ($success) {
|
||||||
|
$message = '<div class="alert alert-success">✅ Daten erfolgreich gespeichert.</div>';
|
||||||
|
} else {
|
||||||
|
$message = '<div class="alert alert-danger">❌ Fehler beim Speichern der Daten.</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Daten neu laden nach dem Speichern (oder beim ersten Aufruf)
|
||||||
|
$hotel = $hotelModel->findByIdWithRelations($hotelId);
|
||||||
|
$anschrift = $hotel['anschrift'];
|
||||||
|
$bankverbindung = $hotel['bankverbindung'];
|
||||||
|
$rganschrift = $hotel['rg_anschrift'] ?? [];
|
||||||
|
$rgbankverbindung = $hotel['rg_bankverbindung'];
|
||||||
|
$rechnungen = $hotelModel->getRechnungen($hotelId);
|
||||||
|
?>
|
||||||
|
<h2>Hotel: <?= htmlspecialchars($hotel['hotelname']) ?></h2>
|
||||||
|
<?= $message ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="id" value="<?= $hotel['id'] ?>">
|
||||||
|
<input type="hidden" name="anschriftid" value="<?= $hotel['anschrift']['id'] ?>">
|
||||||
|
<input type="hidden" name="rg_anschriftid" value="<?= array_key_exists('id', $rganschrift) ? $rganschrift['id'] : null ?>">
|
||||||
|
<input type="hidden" name="bankid" value="<?= $hotel['bankverbindung']['id'] ?>">
|
||||||
|
|
||||||
|
<!-- Tabs Navigation -->
|
||||||
|
<ul class="nav nav-tabs" id="hotelTab" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link active" id="adresse-tab" data-bs-toggle="tab" data-bs-target="#adresse" type="button" role="tab">
|
||||||
|
Anschrift & Bankverbindung
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="rechnung-tab" data-bs-toggle="tab" data-bs-target="#rechnung" type="button" role="tab">
|
||||||
|
Rechnungsdaten
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="archiv-tab" data-bs-toggle="tab" data-bs-target="#archiv" type="button" role="tab">
|
||||||
|
Rechnungsarchiv
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Tabs Content -->
|
||||||
|
<div class="tab-content pt-3" id="hotelTabContent">
|
||||||
|
<!-- Tab 1: Anschrift & Bankverbindung -->
|
||||||
|
<div class="tab-pane fade show active" id="adresse" role="tabpanel">
|
||||||
|
<?php include 'hotel_edit_adresse.php'; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tab 2: Rechnungsdaten -->
|
||||||
|
<div class="tab-pane fade" id="rechnung" role="tabpanel">
|
||||||
|
<?php include 'hotel_edit_rechnung.php'; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tab 3: Rechnungsarchiv -->
|
||||||
|
<div class="tab-pane fade" id="archiv" role="tabpanel">
|
||||||
|
<?php include 'hotel_edit_rechnung_archiv.php'; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary">Speichern</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
102
src/view/hotel_edit_adresse.php
Normal file
102
src/view/hotel_edit_adresse.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="hotelnummer" class="form-label">Hotelnummer</label>
|
||||||
|
<input type="number" class="form-control" id="hotelnummer" name="hotelnummer" min="101"
|
||||||
|
value="<?= htmlspecialchars($hotel['hotelnummer'] ?? '') ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="hotelname" class="form-label">Hotelname</label>
|
||||||
|
<input type="text" class="form-control" id="hotelname" name="hotelname"
|
||||||
|
value="<?= htmlspecialchars($hotel['hotelname'] ?? '') ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="intern" class="form-label">Intern</label>
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="intern" name="intern"
|
||||||
|
<?= ($hotel['intern'] ?? '') === '1' ? 'checked' : '' ?>>
|
||||||
|
<label class="form-check-label" for="intern">Eigenes Hotel</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="status" class="form-label">Status</label>
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="status" name="status"
|
||||||
|
<?= ($hotel['status'] ?? '') === 'aktiv' ? 'checked' : '' ?>>
|
||||||
|
<label class="form-check-label" for="status">Aktiv</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="betreuer" class="form-label">Betreuer</label>
|
||||||
|
<select class="form-select" name="betreuer" id="betreuer">
|
||||||
|
<?php
|
||||||
|
$optionen = ['Moritz', 'Petra', 'Robert', 'Sonstige'];
|
||||||
|
foreach ($optionen as $opt) {
|
||||||
|
$selected = ($hotel['betreuer'] ?? '') === $opt ? 'selected' : '';
|
||||||
|
echo "<option value=\"$opt\" $selected>$opt</option>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5>Anschrift</h5>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="land" class="form-label">Land</label>
|
||||||
|
<input type="text" class="form-control" name="land" value="<?= htmlspecialchars($anschrift['land'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="plz" class="form-label">PLZ</label>
|
||||||
|
<input type="text" class="form-control" name="plz" value="<?= htmlspecialchars($anschrift['plz'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="ort" class="form-label">Ort</label>
|
||||||
|
<input type="text" class="form-control" name="ort" value="<?= htmlspecialchars($anschrift['ort'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="strasse" class="form-label">Straße</label>
|
||||||
|
<input type="text" class="form-control" name="strasse" value="<?= htmlspecialchars($anschrift['strasse'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="ansprechpartner" class="form-label">Ansprechpartner</label>
|
||||||
|
<input type="text" class="form-control" name="ansprechpartner" value="<?= htmlspecialchars($anschrift['ansprechpartner'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="telefon" class="form-label">Telefon</label>
|
||||||
|
<input type="text" class="form-control" name="telefon" value="<?= htmlspecialchars($anschrift['telefon'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="email" class="form-label">E-Mail</label>
|
||||||
|
<input type="email" class="form-control" name="email" value="<?= htmlspecialchars($anschrift['email'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5>Bankverbindung</h5>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="bank" class="form-label">Bank</label>
|
||||||
|
<input type="text" class="form-control" name="bank" value="<?= htmlspecialchars($bankverbindung['bank'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="iban" class="form-label">IBAN</label>
|
||||||
|
<input type="text" class="form-control" name="iban" value="<?= htmlspecialchars($bankverbindung['iban'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="bic" class="form-label">BIC</label>
|
||||||
|
<input type="text" class="form-control" name="bic" value="<?= htmlspecialchars($bankverbindung['bic'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="inhaber" class="form-label">Kontoinhaber</label>
|
||||||
|
<input type="text" class="form-control" name="inhaber" value="<?= htmlspecialchars($bankverbindung['inhaber'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="notiz" class="form-label">Notizen</label>
|
||||||
|
<textarea class="form-control" name="notiz" rows="4"><?= htmlspecialchars($hotel['notiz'] ?? '') ?></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
109
src/view/hotel_edit_rechnung.php
Normal file
109
src/view/hotel_edit_rechnung.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<div class="container">
|
||||||
|
<h5>Rechnungsanschrift</h5>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<label for="land" class="form-label">Abweichender Hotelname</label>
|
||||||
|
<input type="text" class="form-control" name="rg_hotelname" value="<?= htmlspecialchars($hotel['rg_hotelname'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="rg_land" class="form-label">Land</label>
|
||||||
|
<input type="text" class="form-control" name="rg_land" value="<?= htmlspecialchars($rganschrift['land'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label for="rg_plz" class="form-label">PLZ</label>
|
||||||
|
<input type="text" class="form-control" name="rg_plz" value="<?= htmlspecialchars($rganschrift['plz'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="rg_ort" class="form-label">Ort</label>
|
||||||
|
<input type="text" class="form-control" name="rg_ort" value="<?= htmlspecialchars($rganschrift['ort'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="rg_strasse" class="form-label">Straße</label>
|
||||||
|
<input type="text" class="form-control" name="rg_strasse" value="<?= htmlspecialchars($rganschrift['strasse'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="ansprechpartner" class="form-label">Ansprechpartner</label>
|
||||||
|
<input type="text" class="form-control" name="rgansprechpartner" value="<?= htmlspecialchars($rganschrift['ansprechpartner'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="telefon" class="form-label">Telefon</label>
|
||||||
|
<input type="text" class="form-control" name="rgtelefon" value="<?= htmlspecialchars($rganschrift['telefon'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label for="email" class="form-label">E-Mail</label>
|
||||||
|
<input type="email" class="form-control" name="rgemail" value="<?= htmlspecialchars($rganschrift['email'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h5>Umsatzsteuer</h5>
|
||||||
|
<div class="row align-items-end mb-3">
|
||||||
|
<!-- USt-ID -->
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="rg_ustid" class="form-label">USt-ID</label>
|
||||||
|
<input type="text" class="form-control" id="rg_ustid" name="rg_ustid" value="<?= htmlspecialchars($hotel['rg_ustid'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Umsatzsteuer-Optionen -->
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label d-block">Umsatzsteuer-Status</label>
|
||||||
|
<div class="btn-group w-100" role="group" aria-label="Umsatzsteuerstatus">
|
||||||
|
<input type="radio" class="btn-check" name="rg_ustfrei" id="ust0" value="0" autocomplete="off" <?= ($hotel['rg_ustfrei'] ?? 0) == 0 ? 'checked' : '' ?>>
|
||||||
|
<label class="btn btn-outline-primary" for="ust0">Umsatzsteuer pflichtig</label>
|
||||||
|
|
||||||
|
<input type="radio" class="btn-check" name="rg_ustfrei" id="ust1" value="1" autocomplete="off" <?= ($hotel['rg_ustfrei'] ?? 0) == 1 ? 'checked' : '' ?>>
|
||||||
|
<label class="btn btn-outline-primary" for="ust1">Umsatzsteuer befreit</label>
|
||||||
|
|
||||||
|
<input type="radio" class="btn-check" name="rg_ustfrei" id="ust2" value="2" autocomplete="off" <?= ($hotel['rg_ustfrei'] ?? 0) == 2 ? 'checked' : '' ?>>
|
||||||
|
<label class="btn btn-outline-primary" for="ust2">keine VAT-ID vorhanden</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h5>Provision</h5>
|
||||||
|
<div class="row align-items-end mb-3">
|
||||||
|
<!-- Provision -->
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="rg_ustid" class="form-label">Provisionssatz</label>
|
||||||
|
<input type="text" class="form-control" id="provsatz" name="provsatz" value="<?= htmlspecialchars($hotel['provsatz'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Umsatzsteuer-Optionen -->
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label d-block">Provision-Status</label>
|
||||||
|
<div class="btn-group w-100" role="group" aria-label="Provisionstatus">
|
||||||
|
<input type="radio" class="btn-check" name="rg_provmode" id="provmode0" value="vonDenVerkauften" autocomplete="off" <?= ($hotel['rg_provmode'] ?? 0) == 'vonDenVerkauften' ? 'checked' : '' ?>>
|
||||||
|
<label class="btn btn-outline-primary" for="provmode0">von den Verkauften</label>
|
||||||
|
|
||||||
|
<input type="radio" class="btn-check" name="rg_provmode" id="provmode1" value="vonDenBezahlten" autocomplete="off" <?= ($hotel['rg_provmode'] ?? 0) == 'vonDenBezahlten' ? 'checked' : '' ?>>
|
||||||
|
<label class="btn btn-outline-primary" for="provmode1">von den Bezahlten</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5>Rechnungslauf</h5>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<h5>Bankverbindung für Rechnung</h5>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="bank" class="form-label">Bank</label>
|
||||||
|
<input type="text" class="form-control" name="bank" value="<?= htmlspecialchars($rgbankverbindung['bank'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="iban" class="form-label">IBAN</label>
|
||||||
|
<input type="text" class="form-control" name="iban" value="<?= htmlspecialchars($rgbankverbindung['iban'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="bic" class="form-label">BIC</label>
|
||||||
|
<input type="text" class="form-control" name="bic" value="<?= htmlspecialchars($rgbankverbindung['bic'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="inhaber" class="form-label">Kontoinhaber</label>
|
||||||
|
<input type="text" class="form-control" name="inhaber" value="<?= htmlspecialchars($rgbankverbindung['inhaber'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
43
src/view/hotel_edit_rechnung_archiv.php
Normal file
43
src/view/hotel_edit_rechnung_archiv.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php ?>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<table class="table table-bordered table-hover mt-3">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>Rechnungsnummer</th>
|
||||||
|
<th>Rechnungsdatum</th>
|
||||||
|
<th>Zeitraum</th>
|
||||||
|
<th>Rechnungsbetrag</th>
|
||||||
|
<th>Aktionen</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (!empty($rechnungen) && is_array($rechnungen)): ?>
|
||||||
|
<?php foreach ($rechnungen as $r): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($r['hotelnummer']) . '-' . htmlspecialchars($r['lfdnummer']) ?></td>
|
||||||
|
<td><?= date('d.m.Y', strtotime($r['rechnungsdatum'])) ?></td>
|
||||||
|
<td><?= date('d.m.Y', strtotime($r['vondatum'])) . ' - ' . date('d.m.Y', strtotime($r['bisdatum'])) ?></td>
|
||||||
|
<td class="text-end"><?= number_format($r['saldo'], 2, ',', '.') ?> €</td>
|
||||||
|
<td>
|
||||||
|
<a href="/public/rechnungen/<?= $r['pdfdateiname'] ?>" class="btn btn-sm btn-outline-primary" target="_blank">
|
||||||
|
<i class="bi bi-file-earmark-pdf"></i> PDF
|
||||||
|
</a>
|
||||||
|
<form method="post" action="/controller/RechnungController.php" class="d-inline">
|
||||||
|
<input type="hidden" name="aktion" value="senden">
|
||||||
|
<input type="hidden" name="rechnungid" value="<?= $r['id'] ?>">
|
||||||
|
<button type="submit" class="btn btn-sm btn-outline-secondary">
|
||||||
|
<i class="bi bi-envelope"></i> Mail
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="text-center text-muted">Keine Rechnungen vorhanden.</td>
|
||||||
|
</tr>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
71
src/view/hotels.php
Normal file
71
src/view/hotels.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../core/Database.php';
|
||||||
|
|
||||||
|
$pdo = Database::connect();
|
||||||
|
$stmt = $pdo->query("SELECT id, hotelnummer, hotelname, rg_vondatum, rg_bisdatum, status FROM vwl_hotel ORDER BY hotelname");
|
||||||
|
$hotels = $stmt->fetchAll();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h4>Hotel-Liste</h4>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table id="hotelTable" class="table table-striped table-hover align-middle">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th data-column="hotelnummer">Hotel-Nr</th>
|
||||||
|
<th data-column="hotelname">
|
||||||
|
Name
|
||||||
|
<input type="text" id="hotelFilter" class="form-control form-control-sm d-inline-block ms-2" placeholder="Filtern..." style="width: 200px;">
|
||||||
|
</th>
|
||||||
|
<th data-column="rg_vondatum">Von-Datum</th>
|
||||||
|
<th data-column="rg_bisdatum">Bis-Datum</th>
|
||||||
|
<th data-column="status">Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($hotels as $hotel): ?>
|
||||||
|
<tr ondblclick="openHotelForm(<?= $hotel['id'] ?>)">
|
||||||
|
<td><?= htmlspecialchars($hotel['hotelnummer']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($hotel['hotelname']) ?></td>
|
||||||
|
<td><?= isset($hotel['rg_vondatum']) && ($d = DateTime::createFromFormat('Y-m-d', $hotel['rg_vondatum'])) ? $d->format('d.m.Y') : '' ?></td>
|
||||||
|
<td><?= isset($hotel['rg_bisdatum']) && ($d = DateTime::createFromFormat('Y-m-d', $hotel['rg_bisdatum'])) ? $d->format('d.m.Y') : '' ?></td>
|
||||||
|
<td><?= htmlspecialchars($hotel['status']) ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function openHotelForm(id) {
|
||||||
|
window.open('index.php?page=hotel_edit&id=' + id, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sortierung bei Klick auf Überschriften
|
||||||
|
document.querySelectorAll("#hotelTable th").forEach(th => {
|
||||||
|
th.addEventListener("click", () => {
|
||||||
|
const table = th.closest("table");
|
||||||
|
const column = th.cellIndex;
|
||||||
|
const order = th.dataset.order = -(th.dataset.order || -1);
|
||||||
|
const rows = Array.from(table.tBodies[0].rows);
|
||||||
|
|
||||||
|
rows.sort((a, b) => {
|
||||||
|
const cellA = a.cells[column].innerText.trim();
|
||||||
|
const cellB = b.cells[column].innerText.trim();
|
||||||
|
return cellA.localeCompare(cellB, undefined, { numeric: true }) * order;
|
||||||
|
});
|
||||||
|
|
||||||
|
rows.forEach(row => table.tBodies[0].appendChild(row));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Live-Filter für Hotelnamen
|
||||||
|
document.getElementById('hotelFilter').addEventListener('input', function () {
|
||||||
|
const filter = this.value.toLowerCase();
|
||||||
|
const rows = document.querySelectorAll("#hotelTable tbody tr");
|
||||||
|
|
||||||
|
rows.forEach(row => {
|
||||||
|
const hotelname = row.cells[1].innerText.toLowerCase();
|
||||||
|
row.style.display = hotelname.includes(filter) ? '' : 'none';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
3
src/view/templates/footer.php
Normal file
3
src/view/templates/footer.php
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
</div> <!-- container -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
77
src/view/templates/header.php
Normal file
77
src/view/templates/header.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||||
|
session_start();
|
||||||
|
}
|
||||||
|
// Ablaufzeit in Sekunden (15 Minuten)
|
||||||
|
if (!defined('SESSION_TIMEOUT')) {
|
||||||
|
define('SESSION_TIMEOUT', 15 * 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wenn User nicht eingeloggt ist → zur Loginseite
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Session-Timeout prüfen
|
||||||
|
if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > SESSION_TIMEOUT)) {
|
||||||
|
session_unset();
|
||||||
|
session_destroy();
|
||||||
|
header("Location: login.php?timeout=1");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zeit der letzten Aktivität aktualisieren
|
||||||
|
$_SESSION['last_activity'] = time();
|
||||||
|
|
||||||
|
$username = $_SESSION['user'] ?? 'Gast';
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title><?= $pageTitle ?? "Seite" ?> | Meine Anwendung</title>
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<!-- Bootstrap JS (für Tabs) -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<link href="/assets/css/vwl.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="bg-primary text-white py-2 px-4 d-flex justify-content-between align-items-center">
|
||||||
|
<div><strong>Meine Anwendung</strong></div>
|
||||||
|
<div class="text-center flex-grow-1"><?= htmlspecialchars($pageTitle) ?? '' ?></div>
|
||||||
|
<div>Angemeldet als: <?= htmlspecialchars($username) ?></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
|
<?php
|
||||||
|
$menu = [
|
||||||
|
'home' => 'Home',
|
||||||
|
'gutscheinsuche' => 'Gutscheinsuche',
|
||||||
|
'hotels' => 'Hotels',
|
||||||
|
'rechnungen' => 'Rechnungen',
|
||||||
|
'partner' => 'Partner',
|
||||||
|
'auswertungen' => 'Auswertungen',
|
||||||
|
'postversand' => 'Postversand',
|
||||||
|
'einzahlungen' => 'Einzahlungen',
|
||||||
|
'einstellungen' => 'Einstellungen',
|
||||||
|
'direct:/logout.php' => 'Logout'
|
||||||
|
];
|
||||||
|
foreach ($menu as $key => $value) {
|
||||||
|
if (str_starts_with($key, 'direct:')) {
|
||||||
|
$link = substr($key, 7);
|
||||||
|
} else {
|
||||||
|
$link = "?page=$key";
|
||||||
|
}
|
||||||
|
echo "<li class='nav-item'><a class='nav-link' href='$link'>$value</a></li>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
8
web/assets/css/vwl.css
Normal file
8
web/assets/css/vwl.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
Created on : 13.04.2025, 12:22:35
|
||||||
|
Author : KNOB023
|
||||||
|
*/
|
||||||
|
body {
|
||||||
|
font-family: 'Calibri', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
10
web/index.php
Normal file
10
web/index.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once '../core/App.php';
|
||||||
|
|
||||||
|
$app = new App();
|
||||||
60
web/login.php
Normal file
60
web/login.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
if (isset($_GET['timeout']) && $_GET['timeout'] == 1) {
|
||||||
|
echo '<div class="alert alert-warning">Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
require_once '../core/Database.php';
|
||||||
|
|
||||||
|
$pdo = Database::connect();
|
||||||
|
|
||||||
|
$error = null;
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$username = $_POST['username'];
|
||||||
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM vwl_internal_user WHERE vwlusername = :username LIMIT 1");
|
||||||
|
$stmt->execute(['username' => $username]);
|
||||||
|
$user = $stmt->fetch();
|
||||||
|
|
||||||
|
if ($user && password_verify($password, $user['vwlpassword'])) {
|
||||||
|
$_SESSION['user'] = $user['vwlusername'];
|
||||||
|
header("Location: index.php");
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
$error = "Ungültiger Benutzername oder Passwort.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Login</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-light">
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form method="POST">
|
||||||
|
<h3 class="text-center">Login</h3>
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger"><?= $error ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Benutzername</label>
|
||||||
|
<input type="text" name="username" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Passwort</label>
|
||||||
|
<input type="password" name="password" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary w-100" type="submit">Einloggen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
web/logout.php
Normal file
5
web/logout.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
session_destroy();
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
Loading…
Reference in New Issue
Block a user