From a6d0ca0eea6d8b9690a1b1b0d2ec0c491f3f858d Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 8 Oct 2025 00:23:05 +0000 Subject: [PATCH] agenda --- assets/css/custom.css | 52 ++++ assets/js/main.js | 20 ++ db/config.php | 108 +++++++- db/migrations/001_create_agenda_table.php | 15 ++ index.php | 300 ++++++++++++---------- 5 files changed, 340 insertions(+), 155 deletions(-) create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js create mode 100644 db/migrations/001_create_agenda_table.php diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..9297582 --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,52 @@ +body { + background-color: #F4F7F6; + font-family: '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'sans-serif'; + color: #333333; +} + +.header-gradient { + background: linear-gradient(135deg, #4A90E2 0%, #50E3C2 100%); + color: white; +} + +h1, h2, h3, h4, h5, h6 { + font-family: 'Georgia', serif; +} + +.card { + border-radius: 8px; + border: none; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); +} + +.btn-primary { + background-color: #4A90E2; + border-color: #4A90E2; + border-radius: 8px; + padding: 10px 20px; + font-weight: bold; +} + +.btn-primary:hover { + background-color: #357ABD; + border-color: #357ABD; +} + +.nav-tabs .nav-link { + border-radius: 8px 8px 0 0; + border-color: #dee2e6 #dee2e6 #fff; +} + +.nav-tabs .nav-link.active { + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; + color: #4A90E2; + font-weight: bold; +} + +.toast-container { + position: fixed; + top: 20px; + right: 20px; + z-index: 1055; +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..cf76f95 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,20 @@ +(() => { + 'use strict' + + const form = document.querySelector('#agendaForm'); + if (form) { + form.addEventListener('submit', event => { + if (!form.checkValidity()) { + event.preventDefault(); + event.stopPropagation(); + } + form.classList.add('was-validated'); + }, false); + } + + const toastEl = document.querySelector('.toast'); + if (toastEl) { + const toast = new bootstrap.Toast(toastEl); + toast.show(); + } +})(); diff --git a/db/config.php b/db/config.php index 55e7301..7757f26 100644 --- a/db/config.php +++ b/db/config.php @@ -1,17 +1,99 @@ PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ]); - } - return $pdo; + global $db_host, $db_port, $db_name, $db_user, $db_pass; + static $pdo = null; + + if ($pdo !== null) { + return $pdo; + } + + $dsn = "mysql:host={$db_host};port={$db_port};dbname={$db_name};charset=utf8mb4"; + $options = [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]; + + try { + $pdo = new PDO($dsn, $db_user, $db_pass, $options); + return $pdo; + } catch (PDOException $e) { + // In a real application, you would log this error and show a generic error page. + // For this development environment, we'll just show the error. + error_log('Database Connection Error: ' . $e->getMessage()); + // Returning null or you could throw an exception. + return null; + } +} + +/** + * Runs database migrations. + * It finds all .php files in the migrations directory and runs them in order. + * Each migration file should contain a function with the same name as the file (without .php). + */ +function run_migrations() { + $pdo = db(); + if (!$pdo) { + // Cannot run migrations without a database connection. + return; + } + + $migration_dir = __DIR__ . '/migrations'; + if (!is_dir($migration_dir)) { + return; // No migrations directory. + } + + $files = glob($migration_dir . '/*.php'); + sort($files); + + // Check if migrations table exists, create if not + $pdo->exec("CREATE TABLE IF NOT EXISTS migrations (migration VARCHAR(255) PRIMARY KEY)"); + + // Get all executed migrations + $executed_migrations = $pdo->query("SELECT migration FROM migrations")->fetchAll(PDO::FETCH_COLUMN); + + foreach ($files as $file) { + $migration_name = basename($file, '.php'); + + if (in_array($migration_name, $executed_migrations)) { + continue; // Skip already executed migration + } + + require_once $file; + // The function name inside the migration file must match the filename. + // e.g., 001_create_agenda_table.php must contain a function named 'migration_001_create_agenda_table' + $migration_function_name = 'migration_' . str_replace(['-'], '_', $migration_name); + + + if (function_exists($migration_function_name)) { + try { + $pdo->beginTransaction(); + $migration_function_name($pdo); + // Record the migration + $stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)"); + $stmt->execute([$migration_name]); + $pdo->commit(); + } catch (Exception $e) { + $pdo->rollBack(); + error_log("Migration failed: {$migration_name}. Error: " . $e->getMessage()); + // Stop on first failed migration + return; + } + } + } } diff --git a/db/migrations/001_create_agenda_table.php b/db/migrations/001_create_agenda_table.php new file mode 100644 index 0000000..8c8bd6a --- /dev/null +++ b/db/migrations/001_create_agenda_table.php @@ -0,0 +1,15 @@ +exec($sql); +} diff --git a/index.php b/index.php index 7205f3d..ffd255b 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,166 @@ prepare("INSERT INTO agenda (tanggal, waktu, judul, deskripsi) VALUES (?, ?, ?, ?)"); + $stmt->execute([$tanggal, $waktu, $judul, $deskripsi]); + $toast_message = ['type' => 'success', 'message' => 'Agenda berhasil ditambahkan!']; + } catch (PDOException $e) { + error_log($e->getMessage()); + $toast_message = ['type' => 'danger', 'message' => 'Gagal menambahkan agenda.']; + } + } else { + $toast_message = ['type' => 'warning', 'message' => 'Semua kolom wajib diisi.']; + } +} + +// Fetch agenda for the current week +$today = new DateTime(); +$start_of_week = (clone $today)->modify('monday this week'); +$end_of_week = (clone $today)->modify('friday this week'); + +$agendas = []; +if ($pdo) { + $stmt = $pdo->prepare("SELECT * FROM agenda WHERE tanggal BETWEEN ? AND ? ORDER BY tanggal, waktu"); + $stmt->execute([$start_of_week->format('Y-m-d'), $end_of_week->format('Y-m-d')]); + $results = $stmt->fetchAll(); + foreach ($results as $row) { + $day_name = date('l', strtotime($row['tanggal'])); + $agendas[$day_name][] = $row; + } +} + +$days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']; -$phpVersion = PHP_VERSION; -$now = date('Y-m-d H:i:s'); ?> - - + + - - - New Style - - - - - - - - - - - - - - - - - - - + + + Aplikasi Agenda Kegiatan Pimpinan + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+

Agenda Kegiatan Pimpinan

+
+ + +
+
-
- + + +
+
+
+
+
+

Tambah Agenda Baru

+
+
+ + +
Tolong masukkan tanggal.
+
+
+ + +
Tolong masukkan waktu.
+
+
+ + +
Tolong masukkan judul kegiatan.
+
+
+ + +
+ +
+
+
+
+ +
+

Agenda Minggu Ini

+ +
+ $day): ?> +
+ + +
+
+
+
+ +
+

+
+
+ + +
+ +

Tidak ada agenda untuk hari ini.

+
+ +
+ +
+
+
+
+ + + + + + - + \ No newline at end of file