Application #
+ ← Back to Dashboard +Details
+ +Status:
+Personal Information
+Full Name:
+Email:
+Phone:
+Submitted At:
+Insurance Details
+Insurance Type:
+ +diff --git a/README.md b/README.md new file mode 100644 index 0000000..34749ee --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# SecureLife Insurance Application + +This is a comprehensive insurance application system built with PHP. It features a public-facing landing page, a multi-step insurance application form, and a secure, feature-rich admin dashboard. + +## Features + +* **Modern Homepage:** A visually appealing and responsive homepage. +* **Multi-Step Subscription Form:** A user-friendly, multi-step form for insurance applications. +* **Dynamic Form Fields:** The form dynamically shows fields based on the selected insurance type. +* **Admin Dashboard:** A secure admin dashboard to manage and view applications. +* **Application Management:** Admins can view, search, filter, and update the status of applications. +* **Email Notifications:** Automatic email notifications to users and admins upon application submission and status changes. +* **Analytics Chart:** A chart on the admin dashboard to visualize application trends. +* **Details View:** A detailed view for each application. + +## Setup and Installation + +1. **Database:** + * The database configuration is in `db/config.php`. Update the credentials if needed. + * To create the necessary tables, run the migration script: `php db/migrate.php`. + +2. **Email:** + * The email configuration is in `mail/config.php`. You can configure your SMTP settings there. + +## Configuration + +* **Database:** `db/config.php` +* **Email:** `mail/config.php` +* **Admin Credentials:** The admin username and password are currently hardcoded in `admin.php`. It is recommended to move these to a more secure configuration file. + +## Customization + +* **Car Data:** The list of car manufacturers and models can be found and modified in `subscribe-step2.php`. +* **Styling:** The application's styling can be customized in `assets/css/custom.css`. diff --git a/admin-details.php b/admin-details.php new file mode 100644 index 0000000..a20629b --- /dev/null +++ b/admin-details.php @@ -0,0 +1,140 @@ +prepare("SELECT * FROM subscriptions WHERE id = :id"); + $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); + $stmt->execute(); + $subscription = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$subscription) { + $error_message = "Application not found."; + } + } catch (PDOException $e) { + $error_message = "Database error: " . $e->getMessage(); + } +} + +function get_specific_coverage_details_html($sub) { + $type = $sub['insuranceType'] ?? 'N/A'; + $output = ''; + switch ($type) { + case 'Car': + $output .= "
Car Make: " . htmlspecialchars($sub['carMake']) . "
"; + $output .= "Car Model: " . htmlspecialchars($sub['carModel']) . "
"; + $output .= "Year of Manufacture: " . htmlspecialchars($sub['carYear']) . "
"; + break; + case 'Health': + $output .= "Number of Dependents: " . htmlspecialchars($sub['healthDependents']) . "
"; + break; + case 'Life': + $output .= "Coverage Amount: $" . number_format($sub['lifeCoverage'], 2) . "
"; + break; + case 'Home': + $output .= "Property Type: " . htmlspecialchars($sub['homeType']) . "
"; + break; + } + return $output; +} + +// --- Page Setup --- +$page_title = "Application Details"; + +?> + + + + + +Status:
+Full Name:
+Email:
+Phone:
+Submitted At:
+Insurance Type:
+ +Dear {$user_name},
We are pleased to inform you that your application for {$insurance_type} insurance has been approved. Welcome to SecureLife!
We will follow up with your policy documents shortly.
"; + } elseif ($status === 'Rejected') { + $subject = "Update on Your SecureLife Application"; + $body = "Dear {$user_name},
We have carefully reviewed your application for {$insurance_type} insurance. We regret to inform you that we are unable to approve your application at this time.
Thank you for your interest in SecureLife.
"; + } + + if (!empty($subject) && !empty($body)) { + MailService::sendMail($user_email, $subject, $body); + } + } + + } else { + $response['message'] = 'Could not find a subscription with that ID or status is unchanged.'; + } + } catch (Exception $e) { + $response['message'] = 'An error occurred: ' . $e->getMessage(); + } + } else { + $response['message'] = 'Invalid ID or status provided.'; + } +} + +echo json_encode($response); diff --git a/assets/css/custom.css b/assets/css/custom.css index 6d6dd0f..fabd0c3 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,109 +1,155 @@ -/* SecureLife Custom Styles */ -@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap'); + +/* assets/css/custom.css */ :root { - --primary-color: #0052CC; - --secondary-color: #00A3BF; - --bg-light: #F8F9FA; - --surface-white: #FFFFFF; - --text-dark: #212529; - --text-light: #6c757d; - --border-radius: 0.5rem; - --shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); - --shadow-md: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --primary-color: #0A2540; + --accent-color: #00c4ff; + --light-bg: #f8f9fa; + --white: #ffffff; + --font-family: 'Inter', sans-serif; } body { - font-family: 'Poppins', sans-serif; - background-color: var(--bg-light); - color: var(--text-dark); + font-family: var(--font-family); + background-color: var(--white); + color: #333; } +/* Header */ .navbar-brand { + font-family: var(--font-family); font-weight: 700; color: var(--primary-color); } -.hero { - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - color: var(--surface-white); - padding: 6rem 0; - text-align: center; -} - -.hero h1 { - font-weight: 700; - font-size: 3.5rem; -} - -.hero p { - font-size: 1.25rem; - font-weight: 300; - margin-bottom: 2rem; -} - -.btn-primary { +.btn-primary-modern { background-color: var(--primary-color); border-color: var(--primary-color); - font-weight: 600; - padding: 0.75rem 2rem; - border-radius: var(--border-radius); + color: var(--white); + font-weight: 500; + padding: 0.75rem 1.5rem; + border-radius: 0.5rem; transition: all 0.3s ease; } -.btn-primary:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-md); +.btn-primary-modern:hover { + background-color: #001f36; + border-color: #001f36; } -.section-title { +.btn-accent-modern { + background-color: var(--accent-color); + border-color: var(--accent-color); + color: var(--primary-color); font-weight: 700; - margin-bottom: 3rem; - text-align: center; -} - -.accordion-item { - border: 1px solid #dee2e6; - border-radius: var(--border-radius) !important; - margin-bottom: 1rem; - box-shadow: var(--shadow-sm); + padding: 0.75rem 1.5rem; + border-radius: 0.5rem; transition: all 0.3s ease; } -.accordion-item:hover { - transform: translateY(-3px); - box-shadow: var(--shadow-md); +.btn-accent-modern:hover { + background-color: #00a2d1; + border-color: #00a2d1; + transform: translateY(-2px); + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); } -.accordion-header { - border-radius: var(--border-radius); + +/* Hero Section */ +.hero-section { + background: url('https://picsum.photos/1600/900?random=1') no-repeat center center; + background-size: cover; + position: relative; + padding: 8rem 0; } -.accordion-button { - font-weight: 600; - color: var(--text-dark); - border-radius: var(--border-radius) !important; +.hero-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(10, 37, 64, 0.7); } -.accordion-button:not(.collapsed) { - background-color: var(--primary-color); - color: var(--surface-white); - box-shadow: inset 0 -1px 0 rgba(0,0,0,.125); +.hero-section .container { + position: relative; + z-index: 2; } -.accordion-button:focus { - box-shadow: 0 0 0 0.25rem rgba(0, 82, 204, 0.25); +/* Services Section */ +.service-card { + border: none; + border-radius: 0.75rem; + background-color: var(--white); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); + transition: all 0.3s ease; + text-align: center; + padding: 2rem; } -.accordion-body img { - max-width: 150px; - border-radius: var(--border-radius); - box-shadow: var(--shadow-sm); +.service-card:hover { + transform: translateY(-10px); + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.1); } -footer { - background-color: var(--surface-white); - padding: 2rem 0; - margin-top: 4rem; - border-top: 1px solid #e9ecef; +.service-card .icon-box { + width: 80px; + height: 80px; + margin: 0 auto 1.5rem; + border-radius: 50%; + background-color: var(--accent-color); + color: var(--primary-color); + display: flex; + align-items: center; + justify-content: center; + font-size: 2rem; + transition: all 0.3s ease; +} + +.service-card:hover .icon-box { + transform: rotate(360deg); +} + +/* Why Choose Us Section */ +.bg-light-blue { + background-color: #f0f8ff; + border-radius: 1rem; + padding: 4rem 0; +} + +.feature-box { + transition: all 0.3s ease; +} + +.feature-box:hover { + transform: scale(1.05); +} + +.text-primary-modern { + color: var(--primary-color) !important; +} + +/* Footer */ +footer.bg-dark { + background-color: var(--primary-color) !important; +} + +/* Animation */ +.service-card, .feature-box { + opacity: 0; + transform: translateY(20px); + animation: fadeInUp 0.5s forwards; +} + +@keyframes fadeInUp { + to { + opacity: 1; + transform: translateY(0); + } +} + +.row.g-4 > * { + animation-delay: calc(var(--animation-order) * 100ms); } diff --git a/assets/js/main.js b/assets/js/main.js index d73f858..9a5e204 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1 +1,66 @@ -// SecureLife Main JS +function updateStatus(id, status) { + if (!confirm(`Are you sure you want to change the status to "${status}"?`)) { + return; + } + + fetch('api/update-status.php', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ id: id, status: status }), + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + window.location.reload(); + } else { + alert('Error updating status: ' + data.message); + } + }) + .catch(error => { + console.error('Error:', error); + alert('An unexpected error occurred.'); + }); +} + +document.addEventListener('DOMContentLoaded', function() { + const chartCanvas = document.getElementById('applicationsChart'); + if (chartCanvas) { + fetch('/api/chart-data.php') + .then(response => response.json()) + .then(data => { + if (data.success) { + const ctx = chartCanvas.getContext('2d'); + new Chart(ctx, { + type: 'line', + data: { + labels: data.labels, + datasets: [{ + label: 'New Applications', + data: data.data, + fill: false, + borderColor: '#0052CC', + tension: 0.1 + }] + }, + options: { + scales: { + y: { + beginAtZero: true, + ticks: { + stepSize: 1 + } + } + }, + responsive: true, + maintainAspectRatio: false + } + }); + } else { + console.error('Failed to load chart data:', data.message); + } + }) + .catch(error => console.error('Error fetching chart data:', error)); + } +}); diff --git a/config/admin_credentials.php b/config/admin_credentials.php new file mode 100644 index 0000000..e8bc0c6 --- /dev/null +++ b/config/admin_credentials.php @@ -0,0 +1,7 @@ + 'admin', + 'password' => 'password', +]; diff --git a/config/car_data.php b/config/car_data.php new file mode 100644 index 0000000..fe82c79 --- /dev/null +++ b/config/car_data.php @@ -0,0 +1,14 @@ + ['Camry', 'Corolla', 'RAV4', 'Highlander'], + 'Honda' => ['Civic', 'Accord', 'CR-V', 'Pilot'], + 'Ford' => ['F-150', 'Mustang', 'Explorer', 'Escape'], + 'Chevrolet' => ['Silverado', 'Equinox', 'Malibu', 'Tahoe'], + 'Nissan' => ['Rogue', 'Altima', 'Sentra'], + 'Jeep' => ['Wrangler', 'Grand Cherokee'], + 'Hyundai' => ['Elantra', 'Sonata', 'Tucson'], + 'BMW' => ['3 Series', '5 Series', 'X3', 'X5'], + 'Mercedes-Benz' => ['C-Class', 'E-Class', 'GLC'], + 'Audi' => ['A4', 'A6', 'Q5'], +]; diff --git a/db/migrate.php b/db/migrate.php new file mode 100644 index 0000000..00fd182 --- /dev/null +++ b/db/migrate.php @@ -0,0 +1,35 @@ + PDO::ERRMODE_EXCEPTION, + ]); + $pdo_admin->exec("CREATE DATABASE IF NOT EXISTS `" . DB_NAME . "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"); + echo "Database '" . DB_NAME . "' created or already exists.\n"; + + // Now, connect to the specific database to run migrations + $pdo = db(); + $migrationsDir = __DIR__ . '/migrations'; + $files = glob($migrationsDir . '/*.sql'); + + if (empty($files)) { + echo "No migration files found.\n"; + exit; + } + + sort($files); + + foreach ($files as $file) { + echo "Running migration: " . basename($file) . "...\n"; + $sql = file_get_contents($file); + $pdo->exec($sql); + echo "Migration successful.\n"; + } + + echo "All migrations completed.\n"; + +} catch (PDOException $e) { + die("Database migration failed: " . $e->getMessage() . "\n"); +} \ No newline at end of file diff --git a/db/migrations/001_create_subscriptions_table.sql b/db/migrations/001_create_subscriptions_table.sql new file mode 100644 index 0000000..d168f22 --- /dev/null +++ b/db/migrations/001_create_subscriptions_table.sql @@ -0,0 +1,14 @@ +CREATE TABLE IF NOT EXISTS subscriptions ( + id INT AUTO_INCREMENT PRIMARY KEY, + fullName VARCHAR(255) NOT NULL, + email VARCHAR(255) NOT NULL, + phone VARCHAR(50) NOT NULL, + insuranceType VARCHAR(50) NOT NULL, + carMake VARCHAR(100), + carModel VARCHAR(100), + carYear INT, + healthDependents INT, + lifeCoverage DECIMAL(15, 2), + homeType VARCHAR(50), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/db/migrations/002_add_status_to_subscriptions.sql b/db/migrations/002_add_status_to_subscriptions.sql new file mode 100644 index 0000000..16f13e1 --- /dev/null +++ b/db/migrations/002_add_status_to_subscriptions.sql @@ -0,0 +1,2 @@ +ALTER TABLE subscriptions +ADD COLUMN status VARCHAR(50) NOT NULL DEFAULT 'submitted' AFTER homeType; diff --git a/index.php b/index.php index 090a4fa..d0119cc 100644 --- a/index.php +++ b/index.php @@ -3,156 +3,116 @@ - - -Affordable, reliable insurance plans tailored for you.
- Get Your Free Quote +Comprehensive and affordable insurance plans tailored for you.
+ Get Your Free Quote
- Explore our insurance options designed to protect what matters most.
+Hit the road with confidence. Comprehensive coverage against accidents, theft, and damages.
+Your health is your wealth. Access a wide network of hospitals and specialists.
+Secure your family's future. A financial safety net for your loved ones.
+Protect your biggest investment. Coverage from natural disasters to theft.
- We provide more than just insurance. We provide peace of mind.
+With years of experience, we are a name you can trust.
+Our team is always here to help, any time of the day.
+A hassle-free claims process to get you back on your feet.
-
-