Leads Dashboard
+| Lead | +Status | +Category | +Contact | +Owner | ++ |
|---|---|---|---|---|---|
|
+ No leads found. + + |
+ |||||
| + | + + + + | ++ | + | + | + + + | +
diff --git a/add_lead.php b/add_lead.php new file mode 100644 index 0000000..9e5d8b4 --- /dev/null +++ b/add_lead.php @@ -0,0 +1,39 @@ + 'danger', 'text' => 'Invalid input. Please fill all fields correctly.']; + header('Location: index.php'); + exit; + } + + $pdo = db(); + if ($pdo) { + try { + $stmt = $pdo->prepare( + "INSERT INTO leads (lead_name, status, category, contact_email, owner) VALUES (?, ?, ?, ?, ?)" + ); + $stmt->execute([$lead_name, $status, $category, $contact_email, $owner]); + $_SESSION['message'] = ['type' => 'success', 'text' => 'Lead added successfully!']; + } catch (PDOException $e) { + error_log('Add Lead Error: ' . $e->getMessage()); + $_SESSION['message'] = ['type' => 'danger', 'text' => 'A database error occurred.']; + } + } else { + $_SESSION['message'] = ['type' => 'danger', 'text' => 'Could not connect to the database.']; + } +} + +header('Location: index.php'); +exit; +?> \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..fdf384a --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,77 @@ +/* assets/css/custom.css */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); + +:root { + --primary-color: #4A90E2; + --secondary-color: #50E3C2; + --bg-color: #F4F7F9; + --surface-color: #FFFFFF; + --text-color: #333333; + --border-radius-sm: 0.25rem; + --border-radius-md: 0.5rem; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + background-color: var(--bg-color); + color: var(--text-color); +} + +.navbar { + background-color: var(--surface-color); + box-shadow: 0 2px 4px rgba(0,0,0,0.05); +} + +.btn-primary { + background-color: var(--primary-color); + border-color: var(--primary-color); + border-radius: var(--border-radius-sm); +} +.btn-primary:hover { + opacity: 0.9; + background-color: var(--primary-color); + border-color: var(--primary-color); +} + +.gradient-bg { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%); +} + +.main-content { + padding-top: 2rem; +} + +.card { + border: none; + border-radius: var(--border-radius-md); + box-shadow: 0 4px 6px rgba(0,0,0,0.05); +} + +.table { + border-radius: var(--border-radius-md); + overflow: hidden; +} + +.table thead { + background-color: var(--surface-color); +} + +.table th { + border-bottom: 2px solid var(--bg-color); + font-weight: 600; +} + +.status-badge { + padding: 0.3em 0.6em; + border-radius: var(--border-radius-sm); + font-size: 0.8rem; + font-weight: 500; +} +.status-new { background-color: #e9f3ff; color: #4a90e2; } +.status-contacted { background-color: #fff8e1; color: #f5a623; } +.status-qualified { background-color: #e8f5e9; color: #4caf50; } +.status-lost { background-color: #ffebee; color: #f44336; } + +.toast-container { + z-index: 1090; +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..19baf30 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,10 @@ +// assets/js/main.js +document.addEventListener('DOMContentLoaded', function () { + // Initialize Bootstrap toasts if they exist + var toastElList = [].slice.call(document.querySelectorAll('.toast')); + var toastList = toastElList.map(function (toastEl) { + var toast = new bootstrap.Toast(toastEl, { delay: 5000 }); + toast.show(); + return toast; + }); +}); \ No newline at end of file diff --git a/db/config.php b/db/config.php index d630275..215fd48 100644 --- a/db/config.php +++ b/db/config.php @@ -1,17 +1,72 @@ PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ]); - } - return $pdo; +// --- Database Credentials --- +// These are typically stored in environment variables for security +define('DB_HOST', '127.0.0.1'); +define('DB_NAME', 'app_db'); +define('DB_USER', 'app_user'); +define('DB_PASS', 'password'); // Replace with a strong password in a real app + +// --- PDO Helper Function --- +function db(): ?PDO { + static $pdo = null; + + if ($pdo !== null) { + return $pdo; + } + + $dsn = 'mysql:host=' . DB_HOST . ';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) { + error_log('DB Connection Error: ' . $e->getMessage()); + return null; + } } + +// --- Initial Table Setup --- +function setup_database() { + $pdo = db(); + if ($pdo) { + try { + $pdo->exec("CREATE TABLE IF NOT EXISTS leads ( + id INT AUTO_INCREMENT PRIMARY KEY, + lead_name VARCHAR(255) NOT NULL, + status VARCHAR(50) NOT NULL, + category VARCHAR(50) NOT NULL, + contact_email VARCHAR(255) NOT NULL, + owner VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + );"); + + // Add some dummy data if the table is empty + $stmt = $pdo->query("SELECT COUNT(*) FROM leads"); + if ($stmt->fetchColumn() == 0) { + $pdo->exec(" + INSERT INTO leads (lead_name, status, category, contact_email, owner) VALUES + ('Global Corp vs. Local Biz', 'New', 'Corporate', 'ceo@globalcorp.com', 'John Doe'), + ('Smith Divorce Case', 'Contacted', 'Family', 'jane.smith@email.com', 'Jane Smith'), + ('State vs. Anderson', 'Qualified', 'Criminal', 'anderson@email.com', 'John Doe'), + ('Tech Innovations Inc. Patent', 'New', 'Corporate', 'contact@techinnovations.com', 'Jane Smith'), + ('Real Estate Dispute', 'Lost', 'Corporate', 'buyer@realestate.com', 'John Doe'); + "); + } + + } catch (PDOException $e) { + error_log('DB Setup Error: ' . $e->getMessage()); + } + } +} + +// Run setup +setup_database(); + +?> \ No newline at end of file diff --git a/index.php b/index.php index e13ae95..864b779 100644 --- a/index.php +++ b/index.php @@ -1,131 +1,193 @@ query("SELECT id, lead_name, status, category, contact_email, owner FROM leads ORDER BY created_at DESC"); + $leads = $stmt->fetchAll(); + } catch (PDOException $e) { + error_log("Fetch Leads Error: " . $e->getMessage()); + // Set a message to be displayed if fetching fails + $_SESSION['message'] = ['type' => 'danger', 'text' => 'Could not fetch leads from the database.']; + } +} else { + $_SESSION['message'] = ['type' => 'danger', 'text' => 'Database connection failed. Please check configuration.']; +} + +// Get flash message from session +$message = null; +if (isset($_SESSION['message'])) { + $message = $_SESSION['message']; + unset($_SESSION['message']); +} ?> - +
- - -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) ?>
| Lead | +Status | +Category | +Contact | +Owner | ++ |
|---|---|---|---|---|---|
|
+ No leads found. + + |
+ |||||
| + | + + + + | ++ | + | + | + + + | +