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…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
Agenda Minggu Ini
+
+
+ $day): ?>
+
+
+
+
+
+
+
+
+
Tidak ada agenda untuk hari ini.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file