❌ Installation bereits durchgeführt!

Lösche config.php für Neuinstallation oder nutze ?force=1

'); } $error = ''; $success = ''; $step = isset($_GET['step']) ? (int)$_GET['step'] : 1; // SCHRITT 2: Installation durchführen if ($_SERVER['REQUEST_METHOD'] === 'POST' && $step === 2) { try { // Korrekte Datenbankdaten aus vorherigen Chats $host = 'localhost'; $dbname = 'db123456_zeit'; $user = 'db123456_patrick'; $pass = 'Zeit2025!'; $admin_email = trim($_POST['admin_email'] ?? ''); $admin_pass = $_POST['admin_pass'] ?? ''; if (empty($admin_email) || empty($admin_pass)) { throw new Exception('Bitte Admin E-Mail und Passwort eingeben!'); } // Datenbankverbindung testen $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $user, $pass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); // Tabellen erstellen $pdo->exec("DROP TABLE IF EXISTS time_entries, projects, users"); // Users Tabelle $pdo->exec("CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, role ENUM('admin', 'user') DEFAULT 'user', language VARCHAR(2) DEFAULT 'de', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); // Projects Tabelle mit allen neuen Feldern $pdo->exec("CREATE TABLE projects ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, client VARCHAR(255) NOT NULL, description TEXT, address_street VARCHAR(255), address_city VARCHAR(255), address_zip VARCHAR(20), address_country VARCHAR(100), lat DECIMAL(10, 8), lng DECIMAL(11, 8), geofence_enabled BOOLEAN DEFAULT 0, geofence_radius INT DEFAULT 100, materials JSON, tools JSON, active BOOLEAN DEFAULT 1, created_by INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (created_by) REFERENCES users(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); // Time Entries Tabelle $pdo->exec("CREATE TABLE time_entries ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, project_id INT NOT NULL, start_time DATETIME NOT NULL, end_time DATETIME, duration INT, type ENUM('work', 'break', 'travel') DEFAULT 'work', notes TEXT, geofence_verified BOOLEAN DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); // Admin-User erstellen $hashed_password = password_hash($admin_pass, PASSWORD_DEFAULT); $stmt = $pdo->prepare("INSERT INTO users (email, password, name, role) VALUES (?, ?, ?, 'admin')"); $stmt->execute([$admin_email, $hashed_password, 'Admin']); // Demo-Projekte erstellen $demo_project_1 = $pdo->prepare("INSERT INTO projects ( name, client, description, address_street, address_city, address_zip, address_country, lat, lng, geofence_enabled, geofence_radius, materials, tools, created_by ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $materials_1 = json_encode([ ['name' => 'Kabel NYM 3x1.5', 'quantity' => '250', 'unit' => 'm'], ['name' => 'Steckdosen', 'quantity' => '45', 'unit' => 'Stk'], ['name' => 'Leerrohre', 'quantity' => '80', 'unit' => 'm'] ]); $tools_1 = json_encode([ ['name' => 'Bohrmaschine Bosch GSB 13', 'quantity' => '2', 'unit' => 'Stk'], ['name' => 'Akkuschrauber', 'quantity' => '3', 'unit' => 'Stk'], ['name' => 'Leiter 3m', 'quantity' => '2', 'unit' => 'Stk'] ]); $demo_project_1->execute([ 'Bürogebäude Sanierung', 'Müller GmbH', 'Komplettsanierung des Bürogebäudes mit neuer Elektrik und Sanitär. Alle Räume werden neu verkabelt.', 'Hauptstraße 123', 'Stuttgart', '70173', 'Deutschland', 48.7758, 9.1829, 1, 100, $materials_1, $tools_1, 1 ]); // Config-Datei erstellen $config_content = " PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); function isLoggedIn() { return isset(\$_SESSION['user_id']); } function isAdmin() { return isset(\$_SESSION['role']) && \$_SESSION['role'] === 'admin'; } function requireLogin() { if (!isLoggedIn()) { header('Location: login.php'); exit; } } ?>"; file_put_contents('config.php', $config_content); // Login-Seite erstellen $login_content = "prepare('SELECT * FROM users WHERE email = ?'); \$stmt->execute([\$email]); \$user = \$stmt->fetch(); if (\$user && password_verify(\$password, \$user['password'])) { \$_SESSION['user_id'] = \$user['id']; \$_SESSION['user_name'] = \$user['name']; \$_SESSION['role'] = \$user['role']; \$_SESSION['language'] = \$user['language']; header('Location: index.php'); exit; } else { \$error = 'Ungültige Anmeldedaten!'; } } ?> Time Track V 1.1 - Login

⏱️ Time Track

Version 1.1

© 2025 Time Track - Zeiterfassung
"; file_put_contents('login.php', $login_content); // Logout-Seite $logout_content = ""; file_put_contents('logout.php', $logout_content); // API-Datei erstellen $api_content = " false]; try { switch(\$action) { case 'get_projects': \$stmt = \$pdo->prepare('SELECT * FROM projects WHERE active = 1 ORDER BY name'); \$stmt->execute(); \$projects = \$stmt->fetchAll(); // Zeit-Statistiken für jedes Projekt berechnen foreach(\$projects as &\$project) { // Heute \$stmt = \$pdo->prepare(' SELECT SUM(duration) as total FROM time_entries WHERE project_id = ? AND DATE(start_time) = CURDATE() AND user_id = ? '); \$stmt->execute([\$project['id'], \$_SESSION['user_id']]); \$today = \$stmt->fetch(); \$project['time_today'] = \$today['total'] ? gmdate('G:i', \$today['total']) . 'h' : '0:00h'; // Diese Woche \$stmt = \$pdo->prepare(' SELECT SUM(duration) as total FROM time_entries WHERE project_id = ? AND YEARWEEK(start_time) = YEARWEEK(NOW()) AND user_id = ? '); \$stmt->execute([\$project['id'], \$_SESSION['user_id']]); \$week = \$stmt->fetch(); \$project['time_week'] = \$week['total'] ? gmdate('G:i', \$week['total']) . 'h' : '0:00h'; // Gesamt \$stmt = \$pdo->prepare(' SELECT SUM(duration) as total FROM time_entries WHERE project_id = ? AND user_id = ? '); \$stmt->execute([\$project['id'], \$_SESSION['user_id']]); \$total = \$stmt->fetch(); \$project['time_total'] = \$total['total'] ? gmdate('G:i', \$total['total']) . 'h' : '0:00h'; // JSON-Felder dekodieren \$project['materials'] = json_decode(\$project['materials'] ?? '[]', true); \$project['tools'] = json_decode(\$project['tools'] ?? '[]', true); } \$response = ['success' => true, 'projects' => \$projects]; break; case 'save_project': \$data = json_decode(file_get_contents('php://input'), true); if (!\$data['name'] || !\$data['client']) { throw new Exception('Name und Kunde sind Pflichtfelder!'); } if (isset(\$data['id']) && \$data['id']) { // Update \$stmt = \$pdo->prepare(' UPDATE projects SET name = ?, client = ?, description = ?, address_street = ?, address_city = ?, address_zip = ?, address_country = ?, lat = ?, lng = ?, geofence_enabled = ?, geofence_radius = ?, materials = ?, tools = ? WHERE id = ? '); \$stmt->execute([ \$data['name'], \$data['client'], \$data['description'] ?? '', \$data['address']['street'] ?? '', \$data['address']['city'] ?? '', \$data['address']['zipCode'] ?? '', \$data['address']['country'] ?? '', \$data['address']['lat'] ?? null, \$data['address']['lng'] ?? null, \$data['geofence']['enabled'] ?? 0, \$data['geofence']['radius'] ?? 100, json_encode(\$data['materials'] ?? []), json_encode(\$data['tools'] ?? []), \$data['id'] ]); } else { // Insert \$stmt = \$pdo->prepare(' INSERT INTO projects ( name, client, description, address_street, address_city, address_zip, address_country, lat, lng, geofence_enabled, geofence_radius, materials, tools, created_by ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) '); \$stmt->execute([ \$data['name'], \$data['client'], \$data['description'] ?? '', \$data['address']['street'] ?? '', \$data['address']['city'] ?? '', \$data['address']['zipCode'] ?? '', \$data['address']['country'] ?? '', \$data['address']['lat'] ?? null, \$data['address']['lng'] ?? null, \$data['geofence']['enabled'] ?? 0, \$data['geofence']['radius'] ?? 100, json_encode(\$data['materials'] ?? []), json_encode(\$data['tools'] ?? []), \$_SESSION['user_id'] ]); } \$response = ['success' => true]; break; case 'start_work': \$project_id = \$_POST['project_id'] ?? 0; if (!\$project_id) throw new Exception('Projekt-ID fehlt!'); // Check ob bereits eine aktive Session existiert \$stmt = \$pdo->prepare('SELECT id FROM time_entries WHERE user_id = ? AND end_time IS NULL'); \$stmt->execute([\$_SESSION['user_id']]); if (\$stmt->fetch()) { throw new Exception('Es läuft bereits eine Zeiterfassung!'); } \$stmt = \$pdo->prepare('INSERT INTO time_entries (user_id, project_id, start_time, type) VALUES (?, ?, NOW(), \"work\")'); \$stmt->execute([\$_SESSION['user_id'], \$project_id]); \$response = ['success' => true, 'entry_id' => \$pdo->lastInsertId()]; break; case 'stop_work': \$stmt = \$pdo->prepare(' UPDATE time_entries SET end_time = NOW(), duration = TIMESTAMPDIFF(SECOND, start_time, NOW()) WHERE user_id = ? AND end_time IS NULL '); \$stmt->execute([\$_SESSION['user_id']]); \$response = ['success' => true]; break; case 'get_stats': // Heute \$stmt = \$pdo->prepare(' SELECT SUM(duration) as total FROM time_entries WHERE user_id = ? AND DATE(start_time) = CURDATE() '); \$stmt->execute([\$_SESSION['user_id']]); \$today = \$stmt->fetch(); // Diese Woche \$stmt = \$pdo->prepare(' SELECT SUM(duration) as total FROM time_entries WHERE user_id = ? AND YEARWEEK(start_time) = YEARWEEK(NOW()) '); \$stmt->execute([\$_SESSION['user_id']]); \$week = \$stmt->fetch(); // Dieser Monat \$stmt = \$pdo->prepare(' SELECT SUM(duration) as total FROM time_entries WHERE user_id = ? AND MONTH(start_time) = MONTH(NOW()) AND YEAR(start_time) = YEAR(NOW()) '); \$stmt->execute([\$_SESSION['user_id']]); \$month = \$stmt->fetch(); \$response = [ 'success' => true, 'today' => \$today['total'] ? gmdate('G:i', \$today['total']) . 'h' : '0:00h', 'week' => \$week['total'] ? gmdate('G:i', \$week['total']) . 'h' : '0:00h', 'month' => \$month['total'] ? gmdate('G:i', \$month['total']) . 'h' : '0:00h' ]; break; default: throw new Exception('Unbekannte Aktion!'); } } catch(Exception \$e) { \$response = ['success' => false, 'error' => \$e->getMessage()]; } echo json_encode(\$response); ?>"; file_put_contents('api.php', $api_content); // Haupt-App erstellen (index.php) $index_content = file_get_contents(__FILE__); $html_start = strpos($index_content, ''); $html_end = strpos($index_content, ''); $html_content = substr($index_content, $html_start, $html_end - $html_start); $index_final = " $html_content"; file_put_contents('index.php', $index_final); $success = "✅ Installation erfolgreich abgeschlossen!"; $step = 3; } catch(Exception $e) { $error = $e->getMessage(); } } // HTML Output für Installation ?> Time Track V 1.1 - Installation

⏱️ Time Track V 1.1

1
2
3

Willkommen zur Installation!

Time Track V 1.1 installiert sich automatisch mit allen Features:

Verwendete Datenbankdaten:
Host: localhost
Datenbank: db123456_zeit
Benutzer: db123456_patrick
Passwort: Zeit2025!

Schritt 2: Admin-Account erstellen

Legen Sie jetzt Ihren Administrator-Account an.

🎉 Installation erfolgreich!

Time Track V 1.1 wurde erfolgreich installiert.

Erstellte Dateien:
✅ config.php - Konfiguration
✅ login.php - Login-Seite
✅ logout.php - Logout-Funktion
✅ index.php - Haupt-App
✅ api.php - Backend-API

Demo-Projekt:
📁 "Bürogebäude Sanierung" mit Material & Werkzeug
Jetzt anmelden
⚠️ Wichtig: Lösche jetzt die install.php aus Sicherheitsgründen!
Time Track V 1.1