Compare commits

...

2 Commits

Author SHA1 Message Date
Flatlogic Bot
08fcb2dae0 0.2 2025-12-01 21:25:15 +00:00
Flatlogic Bot
0727615032 0.1 2025-12-01 19:31:46 +00:00
28 changed files with 2989 additions and 142 deletions

41
add_user.php Normal file
View File

@ -0,0 +1,41 @@
<?php
session_start();
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'Super Admin') {
header('Location: login.php');
exit;
}
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];
$role = $_POST['role'];
$agent_tier = $_POST['agent_tier'];
$phone = $_POST['phone'];
$company = $_POST['company'];
$notes = $_POST['notes'];
if (empty($name) || empty($email) || empty($password) || empty($role)) {
// Handle empty fields
header('Location: admin_dashboard.php?error=empty_fields');
exit;
}
$db = db();
$hashed_password = password_hash($password, PASSWORD_BCRYPT);
$referral_code = uniqid();
$stmt = $db->prepare('INSERT INTO users (name, email, password, referral_code, role, agent_tier, phone, company, notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
$stmt->execute([$name, $email, $hashed_password, $referral_code, $role, $agent_tier, $phone, $company, $notes]);
header('Location: admin_dashboard.php');
exit;
} else {
header('Location: admin_dashboard.php');
exit;
}
?>

115
admin/bookings.php Normal file
View File

@ -0,0 +1,115 @@
<?php
session_start();
require_once '../auth.php';
require_once '../db/config.php';
require_once '../mlm_logic.php';
// 1. Role-Based Access Control
if (!is_logged_in() || !(is_admin() || is_super_admin())) {
header('Location: ../login.php');
exit;
}
$message = '';
$error = '';
// 2. Process Actions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['booking_id'])) {
$bookingId = $_POST['booking_id'];
$action = $_POST['action'];
$db = db();
if ($action === 'approve') {
try {
// Update booking status
$stmt = $db->prepare("UPDATE bookings SET status = 'approved' WHERE id = :id AND status = 'pending'");
$stmt->execute([':id' => $bookingId]);
// Calculate commissions
calculate_commissions($bookingId);
$message = "Booking #$bookingId has been approved and commissions have been processed.";
} catch (Exception $e) {
$error = "Error approving booking: " . $e->getMessage();
}
} elseif ($action === 'reject') {
$stmt = $db->prepare("UPDATE bookings SET status = 'rejected' WHERE id = :id AND status = 'pending'");
$stmt->execute([':id' => $bookingId]);
$message = "Booking #$bookingId has been rejected.";
}
}
// 3. Fetch Bookings
$db = db();
$stmt = $db->query("SELECT b.*, u.name as user_name, u.email as user_email FROM bookings b JOIN users u ON b.user_id = u.id ORDER BY b.created_at DESC");
$bookings = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Bookings</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="../assets/css/custom.css">
</head>
<body>
<div class="container-fluid mt-4">
<h2>Manage Bookings</h2>
<p>Review, approve, or reject new bookings.</p>
<?php if ($message): ?>
<div class="alert alert-success"><?php echo htmlspecialchars($message); ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>User</th>
<th>Plot ID</th>
<th>Amount</th>
<th>Booking Date</th>
<th>Proof</th>
<th>Status</th>
<th>Submitted At</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($bookings as $booking): ?>
<tr>
<td><?php echo htmlspecialchars($booking['id']); ?></td>
<td><?php echo htmlspecialchars($booking['user_name']); ?><br><small><?php echo htmlspecialchars($booking['user_email']); ?></small></td>
<td><?php echo htmlspecialchars($booking['plot_id']); ?></td>
<td><?php echo number_format($booking['amount'], 2); ?></td>
<td><?php echo htmlspecialchars($booking['booking_date']); ?></td>
<td><a href="../<?php echo htmlspecialchars($booking['proof_document']); ?>" target="_blank">View Proof</a></td>
<td><span class="badge badge-<?php echo $booking['status'] == 'approved' ? 'success' : ($booking['status'] == 'rejected' ? 'danger' : 'warning'); ?>"><?php echo ucfirst(htmlspecialchars($booking['status'])); ?></span></td>
<td><?php echo htmlspecialchars($booking['created_at']); ?></td>
<td>
<?php if ($booking['status'] === 'pending'): ?>
<form action="bookings.php" method="POST" class="d-inline">
<input type="hidden" name="booking_id" value="<?php echo $booking['id']; ?>">
<button type="submit" name="action" value="approve" class="btn btn-success btn-sm">Approve</button>
</form>
<form action="bookings.php" method="POST" class="d-inline">
<input type="hidden" name="booking_id" value="<?php echo $booking['id']; ?>">
<button type="submit" name="action" value="reject" class="btn btn-danger btn-sm">Reject</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<a href="../admin_dashboard.php" class="btn btn-secondary">Back to Dashboard</a>
</div>
</body>
</html>

193
admin/withdrawals.php Normal file
View File

@ -0,0 +1,193 @@
<?php
session_start();
if (!isset($_SESSION['user_id']) || !in_array($_SESSION['role'], ['Admin', 'Super Admin'])) {
header('Location: ../login.php');
exit();
}
require_once '../db/config.php';
$db = db();
$message = '';
$error = '';
// Handle actions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['withdrawal_id'])) {
$withdrawal_id = $_POST['withdrawal_id'];
$action = $_POST['action'];
// Fetch withdrawal details
$stmt = $db->prepare("SELECT * FROM withdrawals WHERE id = ? AND status = 'pending'");
$stmt->execute([$withdrawal_id]);
$withdrawal = $stmt->fetch();
if ($withdrawal) {
try {
$db->beginTransaction();
if ($action === 'approve') {
// Update withdrawal status
$stmt = $db->prepare("UPDATE withdrawals SET status = 'approved', processed_at = CURRENT_TIMESTAMP WHERE id = ?");
$stmt->execute([$withdrawal_id]);
// Update the corresponding transaction description
$stmt = $db->prepare("UPDATE transactions SET description = 'Withdrawal approved and processed' WHERE type = 'withdrawal_request' AND related_withdrawal_id = ?");
$stmt->execute([$withdrawal_id]);
$message = 'Withdrawal has been approved.';
} elseif ($action === 'reject') {
$rejection_reason = $_POST['rejection_reason'] ?? 'Rejected by admin.';
// 1. Update withdrawal status
$stmt = $db->prepare("UPDATE withdrawals SET status = 'rejected', rejection_reason = ?, processed_at = CURRENT_TIMESTAMP WHERE id = ?");
$stmt->execute([$rejection_reason, $withdrawal_id]);
// 2. Refund the amount to the user's wallet
$stmt = $db->prepare("UPDATE users SET wallet_balance = wallet_balance + ? WHERE id = ?");
$stmt->execute([$withdrawal['amount'], $withdrawal['user_id']]);
// 3. Record the reversal transaction
$stmt = $db->prepare("INSERT INTO transactions (user_id, amount, type, description, related_withdrawal_id) VALUES (?, ?, 'withdrawal_reversal', ?, ?)");
$stmt->execute([$withdrawal['user_id'], $withdrawal['amount'], 'Withdrawal request rejected. Amount refunded.', $withdrawal_id]);
// 4. Invalidate the original withdrawal request transaction
$stmt = $db->prepare("UPDATE transactions SET description = 'Withdrawal request rejected' WHERE type = 'withdrawal_request' AND related_withdrawal_id = ?");
$stmt->execute([$withdrawal_id]);
$message = 'Withdrawal has been rejected and the amount refunded.';
}
$db->commit();
} catch (PDOException $e) {
$db->rollBack();
$error = 'Database error: ' . $e->getMessage();
}
} else {
$error = 'Invalid or already processed withdrawal request.';
}
}
// Pagination
$limit = 20;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $limit;
$status_filter = $_GET['status'] ?? 'all';
// Fetch total withdrawals
$count_sql = "SELECT COUNT(*) FROM withdrawals w JOIN users u ON w.user_id = u.id";
$params = [];
if($status_filter !== 'all') {
$count_sql .= " WHERE w.status = ?";
$params[] = $status_filter;
}
$total_stmt = $db->prepare($count_sql);
$total_stmt->execute($params);
$total_withdrawals = $total_stmt->fetchColumn();
$total_pages = ceil($total_withdrawals / $limit);
// Fetch withdrawals with user info
$sql = "SELECT w.*, u.name as user_name, u.email as user_email FROM withdrawals w JOIN users u ON w.user_id = u.id";
if($status_filter !== 'all') {
$sql .= " WHERE w.status = ?";
}
$sql .= " ORDER BY w.created_at DESC LIMIT ? OFFSET ?";
$stmt = $db->prepare($sql);
$params[] = $limit;
$params[] = $offset;
$stmt->execute($params);
$withdrawals = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Withdrawals</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid mt-4">
<h2>Manage Withdrawals</h2>
<a href="../dashboard.php" class="btn btn-secondary mb-3">Back to Dashboard</a>
<?php if ($message) echo "<div class='alert alert-success'>$message</div>"; ?>
<?php if ($error) echo "<div class='alert alert-danger'>$error</div>"; ?>
<ul class="nav nav-tabs">
<li class="nav-item"><a class="nav-link <?php if($status_filter==='all') echo 'active';?>" href="?status=all">All</a></li>
<li class="nav-item"><a class="nav-link <?php if($status_filter==='pending') echo 'active';?>" href="?status=pending">Pending</a></li>
<li class="nav-item"><a class="nav-link <?php if($status_filter==='approved') echo 'active';?>" href="?status=approved">Approved</a></li>
<li class="nav-item"><a class="nav-link <?php if($status_filter==='rejected') echo 'active';?>" href="?status=rejected">Rejected</a></li>
</ul>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr><th>ID</th><th>User</th><th>Amount</th><th>Date</th><th>Status</th><th>Actions</th></tr>
</thead>
<tbody>
<?php foreach ($withdrawals as $w): ?>
<tr>
<td><?php echo $w['id']; ?></td>
<td><?php echo htmlspecialchars($w['user_name']) . '<br><small>' . htmlspecialchars($w['user_email']) . '</small>'; ?></td>
<td><?php echo number_format($w['amount'], 2); ?></td>
<td><?php echo $w['created_at']; ?></td>
<td><span class="badge bg-<?php echo $w['status']=='pending'?'warning':($w['status']=='approved'?'success':'danger'); ?>"><?php echo ucfirst($w['status']); ?></span></td>
<td>
<?php if ($w['status'] === 'pending'): ?>
<form method="POST" class="d-inline"> <!-- Approve Form -->
<input type="hidden" name="withdrawal_id" value="<?php echo $w['id']; ?>">
<input type="hidden" name="action" value="approve">
<button type="submit" class="btn btn-success btn-sm">Approve</button>
</form>
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#rejectModal-<?php echo $w['id']; ?>">Reject</button>
<!-- Reject Modal -->
<div class="modal fade" id="rejectModal-<?php echo $w['id']; ?>" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"><h5 class="modal-title">Reject Withdrawal</h5></div>
<form method="POST">
<div class="modal-body">
<p>Are you sure you want to reject this withdrawal of <?php echo number_format($w['amount'], 2); ?> for <?php echo htmlspecialchars($w['user_name']); ?>?</p>
<input type="hidden" name="withdrawal_id" value="<?php echo $w['id']; ?>">
<input type="hidden" name="action" value="reject">
<div class="mb-3">
<label for="rejection_reason" class="form-label">Reason (Optional)</label>
<textarea class="form-control" name="rejection_reason" rows="2"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-danger">Confirm Rejection</button>
</div>
</form>
</div>
</div>
</div>
<?php else: ?>
Processed on <?php echo $w['processed_at']; ?><br>
<?php if($w['status'] == 'rejected' && $w['rejection_reason']) echo "<small class='text-muted'>Reason: ".htmlspecialchars($w['rejection_reason'])."</small>"; ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!-- Pagination -->
<nav>
<ul class="pagination">
<?php for($i=1; $i<=$total_pages; $i++): ?>
<li class="page-item <?php if($i==$page) echo 'active'; ?>"><a class="page-link" href="?status=<?php echo $status_filter; ?>&page=<?php echo $i; ?>"><?php echo $i; ?></a></li>
<?php endfor; ?>
</ul>
</nav>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

154
admin_dashboard.php Normal file
View File

@ -0,0 +1,154 @@
<?php
session_start();
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'Super Admin') {
header('Location: login.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/dashboard.css?v=<?php echo time(); ?>">
</head>
<body>
<div class="sidebar">
<a href="index.php" class="logo"><i class="bi bi-buildings"></i> Admin Panel</a>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link active" href="admin_dashboard.php"><i class="bi bi-people-fill"></i> User Management</a></li>
<li class="nav-item"><a class="nav-link" href="edit_content.php"><i class="bi bi-pencil-square"></i> Edit Content</a></li>
<li class="nav-item"><a class="nav-link" href="index.php" target="_blank"><i class="bi bi-box-arrow-up-right"></i> View Site</a></li>
<li class="nav-item" style="margin-top: auto;"><hr></li>
<li class="nav-item"><a class="nav-link" href="logout.php"><i class="bi bi-box-arrow-left"></i> Logout</a></li>
</ul>
</div>
<div class="main-content">
<header class="header">
<h1 class="h3 mb-0">User Management</h1>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addUserModal"><i class="bi bi-plus-circle-fill me-2"></i> Add User</button>
</header>
<main class="container-fluid p-4">
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover align-middle">
<thead class="table-light">
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Company</th>
<th>Role</th>
<th>Agent Tier</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php
require_once 'db/config.php';
$db = db();
$stmt = $db->query('SELECT id, name, email, phone, company, role, agent_tier FROM users ORDER BY id DESC');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<tr>";
echo "<td>" . htmlspecialchars($row['id']) . "</td>";
echo "<td>" . htmlspecialchars($row['name']) . "</td>";
echo "<td>" . htmlspecialchars($row['email']) . "</td>";
echo "<td>" . htmlspecialchars($row['phone']) . "</td>";
echo "<td>" . htmlspecialchars($row['company']) . "</td>";
echo "<td><span class=\"badge bg-secondary\">" . htmlspecialchars($row['role']) . "</span></td>";
echo "<td><span class=\"badge bg-info\">" . htmlspecialchars($row['agent_tier']) . "</span></td>";
echo '<td>
<a href="edit_user.php?id=' . $row['id'] . '" class="btn btn-sm btn-outline-primary"><i class="bi bi-pencil-fill"></i></a>
<a href="delete_user.php?id=' . $row['id'] . '" class="btn btn-sm btn-outline-danger" onclick="return confirm(\'Are you sure you want to delete this user?\');"><i class="bi bi-trash-fill"></i></a>
</td>';
echo "</tr>";
}
?>
</tbody>
</table>
</div>
</div>
</div>
</main>
</div>
<!-- Add User Modal -->
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addUserModalLabel">Add New User</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="add_user.php" method="POST">
<div class="row">
<div class="col-md-6 mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="col-md-6 mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="phone" class="form-label">Phone</label>
<input type="text" class="form-control" id="phone" name="phone">
</div>
<div class="col-md-6 mb-3">
<label for="company" class="form-label">Company</label>
<input type="text" class="form-control" id="company" name="company">
</div>
</div>
<div class="mb-3">
<label for="notes" class="form-label">Notes</label>
<textarea class="form-control" id="notes" name="notes" rows="3"></textarea>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="role" class="form-label">Role</label>
<select class="form-select" id="role" name="role">
<option value="Agent">Agent</option>
<option value="Finance">Finance</option>
<option value="Support">Support</option>
<option value="Admin">Admin</option>
<option value="Super Admin">Super Admin</option>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="agent_tier" class="form-label">Agent Tier</label>
<select class="form-select" id="agent_tier" name="agent_tier">
<option value="Normal">Normal</option>
<option value="Silver">Silver</option>
<option value="Gold">Gold</option>
<option value="Diamond">Diamond</option>
</select>
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Add User</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

33
ai_agent.php Normal file
View File

@ -0,0 +1,33 @@
<?php
require_once __DIR__ . '/ai/LocalAIApi.php';
$request_body = file_get_contents('php://input');
$data = json_decode($request_body, true);
$user_message = $data['message'];
if (empty($user_message)) {
echo json_encode(['reply' => 'Please provide a message.']);
exit;
}
$resp = LocalAIApi::createResponse([
'input' => [
['role' => 'system', 'content' => 'You are a helpful assistant for a real estate MLM company called Kutumbh Infra.'],
['role' => 'user', 'content' => $user_message],
],
]);
if (!empty($resp['success'])) {
$text = LocalAIApi::extractText($resp);
if ($text === '') {
$decoded = LocalAIApi::decodeJsonFromResponse($resp);
$text = $decoded ? json_encode($decoded, JSON_UNESCAPED_UNICODE) : (string)($resp['data'] ?? '');
}
$aiReply = $text;
} else {
error_log('AI error: ' . ($resp['error'] ?? 'unknown'));
$aiReply = 'Sorry, I am having trouble connecting to the AI service.';
}
header('Content-Type: application/json');
echo json_encode(['reply' => $aiReply]);

132
assets/css/auth.css Normal file
View File

@ -0,0 +1,132 @@
:root {
--primary-color: #6a11cb;
--secondary-color: #2575fc;
--input-bg: #f0f2f5;
--text-color: #333;
--light-text-color: #777;
--card-bg: #ffffff;
--box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
}
.auth-wrapper {
font-family: 'Poppins', sans-serif;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-color);
}
.auth-container {
display: flex;
width: 100%;
max-width: 1000px;
background-color: var(--card-bg);
border-radius: 20px;
box-shadow: var(--box-shadow);
overflow: hidden;
min-height: 600px;
}
.auth-form-section {
flex: 1;
padding: 3rem 2.5rem;
display: flex;
flex-direction: column;
justify-content: center;
}
.auth-branding-section {
flex: 1;
background: linear-gradient(135deg, var(--secondary-color), var(--primary-color));
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 3rem;
}
.auth-branding-section h1 {
font-weight: 700;
font-size: 2.5rem;
margin-bottom: 1rem;
}
.auth-branding-section p {
font-size: 1.1rem;
max-width: 350px;
}
.auth-form-section h2 {
font-weight: 600;
font-size: 2rem;
margin-bottom: 0.5rem;
}
.auth-form-section .lead {
color: var(--light-text-color);
margin-bottom: 2rem;
}
.form-label {
font-weight: 500;
}
.form-control {
background-color: var(--input-bg);
border: none;
border-radius: 10px;
padding: 12px 15px;
transition: all 0.3s ease;
}
.form-control:focus {
background-color: var(--card-bg);
box-shadow: none;
border: 1px solid var(--primary-color);
}
.input-group-text {
background-color: var(--input-bg);
border: none;
border-radius: 10px 0 0 10px;
}
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border: none;
border-radius: 10px;
padding: 12px;
font-weight: 600;
letter-spacing: 0.5px;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
.auth-form-section a {
color: var(--primary-color);
text-decoration: none;
font-weight: 500;
}
.auth-form-section a:hover {
text-decoration: underline;
}
@media (max-width: 768px) {
.auth-container {
flex-direction: column;
}
.auth-branding-section {
display: none; /* Or a simplified version */
}
}

250
assets/css/dashboard.css Normal file
View File

@ -0,0 +1,250 @@
:root {
--primary-color: #6f42c1;
--secondary-color: #f8f9fa;
--text-color: #343a40;
--heading-font: 'Poppins', sans-serif;
--body-font: 'Poppins', sans-serif;
--sidebar-bg: #1e1e2d;
--sidebar-text: #a5a5a9;
--sidebar-active: #ffffff;
--content-bg: #f4f7f6;
}
body {
font-family: var(--body-font);
color: var(--text-color);
background-color: var(--content-bg);
}
.sidebar {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 260px;
background-color: var(--sidebar-bg);
padding-top: 20px;
transition: all 0.3s;
z-index: 1000;
}
.sidebar .logo {
font-family: var(--heading-font);
font-weight: 700;
color: var(--sidebar-active) !important;
font-size: 1.5rem;
text-align: center;
display: block;
margin-bottom: 30px;
}
.sidebar .nav-link {
color: var(--sidebar-text);
font-weight: 500;
padding: 12px 25px;
display: flex;
align-items: center;
transition: all 0.3s;
}
.sidebar .nav-link i {
margin-right: 15px;
font-size: 1.1rem;
width: 20px;
text-align: center;
}
.sidebar .nav-link:hover,
.sidebar .nav-link.active {
color: var(--sidebar-active);
background-color: rgba(255, 255, 255, 0.05);
}
.sidebar .nav-item-header {
text-transform: uppercase;
font-size: 0.8rem;
font-weight: 600;
color: #4a4a5a;
padding: 10px 25px;
margin-top: 15px;
}
.main-content {
margin-left: 260px;
padding: 0;
transition: all 0.3s;
}
.header {
background-color: #fff;
padding: 20px 30px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #e5e9f2;
}
.wallet-card {
background: linear-gradient(135deg, var(--primary-color), #2575fc);
color: white;
border-radius: 15px;
}
.wallet-balance {
font-weight: 700;
}
.income-card {
background: #fff;
border: none;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
}
.income-card .card-body {
display: flex;
align-items: center;
}
.income-card .icon {
font-size: 2.5rem;
margin-right: 20px;
padding: 20px;
border-radius: 50%;
background-color: rgba(0,0,0,0.05);
}
.table-striped > tbody > tr:nth-of-type(odd) > * {
background-color: rgba(0,0,0,0.02);
}
.feature-card {
background: white;
border-radius: 10px;
padding: 40px;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
transition: transform 0.3s;
}
.feature-card:hover {
transform: translateY(-10px);
}
.feature-icon {
font-size: 3rem;
color: var(--primary-color);
margin-bottom: 20px;
}
.chat-open-button {
position: fixed;
bottom: 20px;
right: 20px;
background-color: var(--primary-color);
color: white;
padding: 15px 20px;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
z-index: 1000;
border: none;
font-size: 24px;
}
.chat-popup {
display: none;
position: fixed;
bottom: 20px;
right: 20px;
width: 350px;
height: 500px;
background-color: white;
flex-direction: column;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
z-index: 1001;
}
.chat-header {
background-color: var(--primary-color);
color: white;
padding: 15px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.chat-messages {
flex-grow: 1;
padding: 15px;
overflow-y: auto;
background-color: #f9f9f9;
}
.chat-input {
display: flex;
padding: 10px;
border-top: 1px solid #ddd;
}
.chat-message {
margin-bottom: 10px;
padding: 8px 12px;
border-radius: 18px;
max-width: 80%;
}
.user-message {
background-color: var(--primary-color);
color: white;
align-self: flex-end;
margin-left: auto;
}
.bot-message {
background-color: #e9e9eb;
color: var(--text-color);
align-self: flex-start;
}
.nav-link-custom {
font-weight: 500;
color: var(--text-color);
transition: color 0.3s;
position: relative;
padding-bottom: 0.5rem;
}
.nav-link-custom::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background-color: var(--primary-color);
transition: width 0.3s ease-in-out;
}
.nav-link-custom:hover::after, .nav-link-custom.active::after {
width: 100%;
}
.nav-link-custom:hover {
color: var(--primary-color);
}
.navbar-nav .btn {
margin-left: 0.5rem;
}
.btn-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.btn-primary:hover {
background-color: #5a3e9a;
border-color: #5a3e9a;
}
.btn-outline-secondary:hover {
background-color: var(--primary-color);
color: white;
}

BIN
assets/images/about-us.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

110
auth.php Normal file
View File

@ -0,0 +1,110 @@
<?php
session_start();
require_once 'db/config.php';
function register($name, $email, $password, $sponsor_code) {
$db = db();
$sponsor_id = null;
if ($sponsor_code) {
$stmt = $db->prepare("SELECT id FROM users WHERE referral_code = ?");
$stmt->execute([$sponsor_code]);
$sponsor = $stmt->fetch();
if (!$sponsor) {
return 'Invalid sponsor code.';
}
$sponsor_id = $sponsor['id'];
}
$password_hash = password_hash($password, PASSWORD_BCRYPT);
$referral_code = uniqid();
try {
$stmt = $db->prepare("INSERT INTO users (name, email, password, referral_code, sponsor_id, role, agent_tier) VALUES (?, ?, ?, ?, ?, 'Agent', 'Normal')");
$stmt->execute([$name, $email, $password_hash, $referral_code, $sponsor_id]);
return true;
} catch (PDOException $e) {
if ($e->errorInfo[1] == 1062) {
return 'Email already exists.';
}
return $e->getMessage();
}
}
function login($email, $password) {
$db = db();
$stmt = $db->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['role'] = $user['role'];
return true;
}
return false;
}
function get_user_by_id($id) {
$db = db();
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch();
}
function get_downline($user_id) {
$db = db();
$stmt = $db->prepare("SELECT * FROM users WHERE sponsor_id = ?");
$stmt->execute([$user_id]);
return $stmt->fetchAll();
}
function is_logged_in() {
return isset($_SESSION['user_id']);
}
function is_admin() {
return isset($_SESSION['role']) && $_SESSION['role'] === 'Admin';
}
function is_super_admin() {
return isset($_SESSION['role']) && $_SESSION['role'] === 'Super Admin';
}
function is_agent() {
return isset($_SESSION['role']) && $_SESSION['role'] === 'Agent';
}
function update_agent_tier($user_id) {
$db = db();
$stmt = $db->prepare("SELECT cumulative_bookings, agent_tier FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
if (!$user) {
return;
}
$cumulative_bookings = $user['cumulative_bookings'];
$current_tier = $user['agent_tier'];
$new_tier = 'Normal';
// Tier thresholds in INR
$tier_thresholds = [
'Diamond' => 1000000,
'Gold' => 500000,
'Silver' => 100000,
'Normal' => 0
];
foreach ($tier_thresholds as $tier => $threshold) {
if ($cumulative_bookings >= $threshold) {
$new_tier = $tier;
break;
}
}
if ($new_tier !== $current_tier) {
$stmt = $db->prepare("UPDATE users SET agent_tier = ? WHERE id = ?");
$stmt->execute([$new_tier, $user_id]);
}
}

25
contact_error.php Normal file
View File

@ -0,0 +1,25 @@
<?php
session_start();
$content = json_decode(file_get_contents('content.json'), true);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Error | <?php echo htmlspecialchars($content['site_title']); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/css/dashboard.css?v=<?php echo time(); ?>" rel="stylesheet">
</head>
<body>
<div class="container text-center mt-5">
<div class="card" style="max-width: 500px; margin: auto;">
<div class="card-body">
<h1 class="card-title text-danger">Something went wrong!</h1>
<p class="card-text">There was an error sending your message. Please try again later.</p>
<a href="index.php#contact" class="btn btn-primary">Go back and try again</a>
</div>
</div>
</div>
</body>
</html>

25
contact_success.php Normal file
View File

@ -0,0 +1,25 @@
<?php
session_start();
$content = json_decode(file_get_contents('content.json'), true);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Message Sent | <?php echo htmlspecialchars($content['site_title']); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/css/dashboard.css?v=<?php echo time(); ?>" rel="stylesheet">
</head>
<body>
<div class="container text-center mt-5">
<div class="card" style="max-width: 500px; margin: auto;">
<div class="card-body">
<h1 class="card-title text-success">Message Sent!</h1>
<p class="card-text">Thank you for contacting us. We will get back to you shortly.</p>
<a href="index.php" class="btn btn-primary">Go back to Homepage</a>
</div>
</div>
</div>
</body>
</html>

19
content.json Normal file
View File

@ -0,0 +1,19 @@
{
"site_title": "Kutumbh Infra - Welcome to the Future of Real Estate",
"site_name": "Kutumbh Infra",
"hero_title": "Welcome to the Future of Real Estate",
"hero_subtitle": "Your partner in building a successful real estate business.",
"about_us_title": "About Our Mission",
"about_us_content_1": "We are dedicated to redefining the real estate landscape. Our mission is to empower individuals to achieve financial independence through our innovative multi-level marketing (MLM) platform.",
"about_us_content_2": "Our company is built on a foundation of integrity, transparency, and a deep understanding of the real estate market. We provide our members with the tools, training, and support they need to thrive.",
"features_title": "Why Choose Us?",
"feature_1_title": "Innovative Platform",
"feature_1_content": "Access a wide range of properties with our user-friendly platform, designed for you to easily search, filter, and manage listings.",
"feature_2_title": "Growth Opportunity",
"feature_2_content": "Our MLM program is designed to help you build a successful business with a competitive commission structure and a supportive community.",
"feature_3_title": "Cutting-Edge Tools",
"feature_3_content": "We provide advanced analytics, marketing materials, and a CRM system to help you manage leads and close deals efficiently.",
"contact_us_title": "Get In Touch",
"contact_us_content": "Have questions? We're here to help. Reach out to us to learn more about our program and join the Kutumbh Infra family.",
"contact_us_button_text": "Contact Us Now"
}

View File

@ -0,0 +1,60 @@
<?php
// This script is designed to be run from the command line by a cron job.
// e.g., 0 1 * * * /usr/bin/php /path/to/your/project/cron/process_passive_income.php
require_once dirname(__DIR__) . '/db/config.php';
echo "Starting passive income processing...\n";
$db = db();
$db->beginTransaction();
try {
// 1. Find pending payments
$stmt = $db->prepare("SELECT * FROM passive_income_schedule WHERE status = 'pending' AND payment_date <= CURDATE()");
$stmt->execute();
$pending_payments = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($pending_payments)) {
echo "No pending passive income payments to process.\n";
$db->commit();
exit;
}
echo "Found " . count($pending_payments) . " pending payment(s).\n";
foreach ($pending_payments as $payment) {
$userId = $payment['user_id'];
$amount = $payment['amount'];
$scheduleId = $payment['id'];
// 2. Insert into transactions
$trans_stmt = $db->prepare(
"INSERT INTO transactions (user_id, amount, type, description, related_user_id) VALUES (:user_id, :amount, 'passive_income', :description, NULL)"
);
$trans_stmt->execute([
':user_id' => $userId,
':amount' => $amount,
':description' => 'Monthly passive income payment from schedule #' . $scheduleId
]);
// 3. Update user's wallet
$user_stmt = $db->prepare("UPDATE users SET wallet_balance = wallet_balance + :amount, total_passive_income = total_passive_income + :amount WHERE id = :user_id");
$user_stmt->execute([':amount' => $amount, ':user_id' => $userId]);
// 4. Update schedule status to 'paid'
$schedule_stmt = $db->prepare("UPDATE passive_income_schedule SET status = 'paid' WHERE id = :id");
$schedule_stmt->execute([':id' => $scheduleId]);
echo "Processed payment for user #$userId (Amount: $amount).\n";
}
$db->commit();
echo "Passive income processing finished successfully.\n";
} catch (Exception $e) {
$db->rollBack();
echo "Error processing passive income: " . $e->getMessage() . "\n";
// It's crucial to log this error to a file in a real-world scenario
error_log("Passive Income Cron Failed: " . $e->getMessage());
}

186
dashboard.php Normal file
View File

@ -0,0 +1,186 @@
<?php
session_start();
require_once 'auth.php';
require_once 'db/config.php';
if (!is_logged_in()) {
header("Location: login.php");
exit;
}
$db = db();
$stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute([':id' => $_SESSION['user_id']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// Fetch last 5 transactions
$stmt = $db->prepare("SELECT * FROM transactions WHERE user_id = :user_id ORDER BY created_at DESC LIMIT 5");
$stmt->execute([':user_id' => $_SESSION['user_id']]);
$recent_transactions = $stmt->fetchAll(PDO::FETCH_ASSOC);
$site_name = 'Kutumbh Infra';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - <?php echo htmlspecialchars($site_name); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="assets/css/dashboard.css?v=<?php echo time(); ?>" rel="stylesheet">
</head>
<body>
<div class="sidebar">
<a href="index.php" class="logo"><i class="bi bi-buildings"></i> <?php echo htmlspecialchars($site_name); ?></a>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link active" href="dashboard.php"><i class="bi bi-grid-1x2-fill"></i> Dashboard</a></li>
<?php if (is_agent()): ?>
<li class="nav-item"><a class="nav-link" href="submit_booking.php"><i class="bi bi-journal-plus"></i> Submit Booking</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="genealogy.php"><i class="bi bi-diagram-3-fill"></i> Genealogy Tree</a></li>
<li class="nav-item"><a class="nav-link" href="ledger.php"><i class="bi bi-receipt-cutoff"></i> Ledger</a></li>
<li class="nav-item"><a class="nav-link" href="withdraw.php"><i class="bi bi-cash-stack"></i> Withdraw</a></li>
<?php if (is_admin() || is_super_admin()): ?>
<li class="nav-item-header">Admin Menu</li>
<li class="nav-item"><a class="nav-link" href="admin/bookings.php"><i class="bi bi-calendar-check-fill"></i> Manage Bookings</a></li>
<?php endif; ?>
<?php if (is_super_admin()): ?>
<li class="nav-item"><a class="nav-link" href="admin_dashboard.php"><i class="bi bi-people-fill"></i> User Management</a></li>
<li class="nav-item"><a class="nav-link" href="edit_content.php"><i class="bi bi-pencil-square"></i> Edit Content</a></li>
<?php endif; ?>
<li class="nav-item" style="margin-top: auto;"><hr></li>
<li class="nav-item"><a class="nav-link" href="logout.php"><i class="bi bi-box-arrow-left"></i> Logout</a></li>
</ul>
</div>
<div class="main-content">
<header class="header">
<h1 class="h3 mb-0">Dashboard</h1>
<div class="dropdown">
<a href="#" class="d-block link-dark text-decoration-none dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle fs-4"></i> <span class="d-none d-sm-inline mx-1"><?php echo htmlspecialchars($user['name']); ?></span>
</a>
<ul class="dropdown-menu text-small dropdown-menu-end">
<li><span class="dropdown-item-text"><strong><?php echo htmlspecialchars($user['name']); ?></strong><br><small><?php echo htmlspecialchars($user['role']); ?></small></span></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="logout.php">Sign out</a></li>
</ul>
</div>
</header>
<main class="container-fluid p-4">
<!-- Wallet Summary -->
<div class="row">
<div class="col-12">
<div class="card wallet-card mb-4">
<div class="card-body p-4 text-center">
<h5 class="card-title">Wallet Balance</h5>
<p class="wallet-balance display-4"><?php echo number_format($user['wallet_balance'], 2); ?></p>
<a href="withdraw.php" class="btn btn-light">Request Withdrawal <i class="bi bi-arrow-right-short"></i></a>
</div>
</div>
</div>
</div>
<!-- Income Breakdown -->
<div class="row">
<div class="col-lg-3 col-md-6 mb-4">
<div class="card income-card">
<div class="card-body">
<div class="icon text-primary"><i class="bi bi-person-check-fill"></i></div>
<div>
<h6 class="card-title text-muted">Direct Income</h6>
<p class="card-text fs-4 fw-bold"><?php echo number_format($user['total_direct_income'], 2); ?></p>
</div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 mb-4">
<div class="card income-card">
<div class="card-body">
<div class="icon text-success"><i class="bi bi-people-fill"></i></div>
<div>
<h6 class="card-title text-muted">Team Income</h6>
<p class="card-text fs-4 fw-bold"><?php echo number_format($user['total_team_income'], 2); ?></p>
</div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 mb-4">
<div class="card income-card">
<div class="card-body">
<div class="icon text-warning"><i class="bi bi-link-45deg"></i></div>
<div>
<h6 class="card-title text-muted">Leg Match Bonus</h6>
<p class="card-text fs-4 fw-bold"><?php echo number_format($user['total_leg_match_income'], 2); ?></p>
</div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 mb-4">
<div class="card income-card">
<div class="card-body">
<div class="icon text-info"><i class="bi bi-arrow-down-up"></i></div>
<div>
<h6 class="card-title text-muted">Passive Income</h6>
<p class="card-text fs-4 fw-bold"><?php echo number_format($user['total_passive_income'], 2); ?></p>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Transactions -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-white border-0">
<h5 class="mb-0">Recent Transactions</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped align-middle">
<thead class="table-light">
<tr>
<th>Date</th>
<th>Type</th>
<th>Amount</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<?php if (empty($recent_transactions)): ?>
<tr><td colspan="4" class="text-center py-5">No recent transactions.</td></tr>
<?php else: ?>
<?php foreach ($recent_transactions as $tx): ?>
<tr>
<td><?php echo date('d M Y, H:i', strtotime($tx['created_at'])); ?></td>
<td><span class="badge bg-info-light text-info-dark"><?php echo ucwords(str_replace('_', ' ', $tx['type'])); ?></span></td>
<td class="fw-bold <?php echo $tx['amount'] > 0 ? 'text-success' : 'text-danger'; ?>"><?php echo number_format($tx['amount'], 2); ?></td>
<td><?php echo htmlspecialchars($tx['description']); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="text-center mt-3">
<a href="ledger.php">View All Transactions</a>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

164
db/setup.php Normal file
View File

@ -0,0 +1,164 @@
<?php
require_once 'db/config.php';
function run_sql($db, $sql, $message) {
try {
$db->exec($sql);
echo $message . "<br>";
} catch (PDOException $e) {
// Suppress errors if the alteration already exists, but show others
if (!str_contains($e->getMessage(), 'Duplicate') && !str_contains($e->getMessage(), 'already exists') && !str_contains($e->getMessage(), 'Unknown table')) {
echo "Error: " . $e->getMessage() . "<br>";
}
}
}
try {
$db = db();
// 0. Drop dependent tables first to avoid foreign key issues
run_sql($db, "DROP TABLE IF EXISTS `passive_income_schedule`", "Table 'passive_income_schedule' dropped if exists.");
run_sql($db, "DROP TABLE IF EXISTS `commissions`", "Table 'commissions' dropped if exists.");
run_sql($db, "DROP TABLE IF EXISTS `wallet_ledger`", "Table 'wallet_ledger' dropped if exists.");
// 1. Users table
$sqlUsers = "CREATE TABLE IF NOT EXISTS `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`email` VARCHAR(255) NOT NULL UNIQUE,
`password` VARCHAR(255) NOT NULL,
`referral_code` VARCHAR(50) NOT NULL UNIQUE,
`sponsor_id` INT NULL,
`role` ENUM('Super Admin', 'Admin', 'Finance', 'Agent', 'Support') NOT NULL DEFAULT 'Agent',
`agent_tier` ENUM('Normal', 'Silver', 'Gold', 'Diamond') NULL DEFAULT 'Normal',
`cumulative_bookings` DECIMAL(15, 2) DEFAULT 0.00,
`phone` VARCHAR(255) NULL,
`company` VARCHAR(255) NULL,
`notes` TEXT NULL,
`wallet_balance` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`total_direct_income` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`total_team_income` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`total_passive_income` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`total_leg_match_income` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sponsor_id) REFERENCES users(id) ON DELETE SET NULL
)";
run_sql($db, $sqlUsers, "Table 'users' created or already exists.");
// Add columns to users table if they don't exist
run_sql($db, "ALTER TABLE users ADD COLUMN wallet_balance DECIMAL(15, 2) NOT NULL DEFAULT 0.00", "Column 'wallet_balance' added to 'users' table.");
run_sql($db, "ALTER TABLE users ADD COLUMN total_direct_income DECIMAL(15, 2) NOT NULL DEFAULT 0.00", "Column 'total_direct_income' added to 'users' table.");
run_sql($db, "ALTER TABLE users ADD COLUMN total_team_income DECIMAL(15, 2) NOT NULL DEFAULT 0.00", "Column 'total_team_income' added to 'users' table.");
run_sql($db, "ALTER TABLE users ADD COLUMN total_passive_income DECIMAL(15, 2) NOT NULL DEFAULT 0.00", "Column 'total_passive_income' added to 'users' table.");
run_sql($db, "ALTER TABLE users ADD COLUMN total_leg_match_income DECIMAL(15, 2) NOT NULL DEFAULT 0.00", "Column 'total_leg_match_income' added to 'users' table.");
run_sql($db, "ALTER TABLE users MODIFY cumulative_bookings DECIMAL(15, 2) DEFAULT 0.00", "Column 'cumulative_bookings' in 'users' table modified.");
run_sql($db, "ALTER TABLE users MODIFY `role` ENUM('Super Admin', 'Admin', 'Finance', 'Agent', 'Support') NOT NULL DEFAULT 'Agent'", "Column 'role' in 'users' table modified.");
// 2. Bookings table
$sqlBookings = "CREATE TABLE IF NOT EXISTS `bookings` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT NOT NULL,
`plot_id` VARCHAR(255) NOT NULL,
`amount` DECIMAL(15, 2) NOT NULL,
`booking_date` DATE NOT NULL,
`proof_document` VARCHAR(255) NOT NULL,
`status` ENUM('pending', 'approved', 'rejected') NOT NULL DEFAULT 'pending',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)";
run_sql($db, $sqlBookings, "Table 'bookings' created or already exists.");
run_sql($db, "ALTER TABLE bookings MODIFY amount DECIMAL(15, 2) NOT NULL", "Column 'amount' in 'bookings' table modified.");
// 3. Transactions table (replaces wallet_ledger and commissions)
$sqlTransactions = "CREATE TABLE IF NOT EXISTS `transactions` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT NOT NULL,
`amount` DECIMAL(15, 2) NOT NULL,
`type` ENUM('commission_direct', 'commission_team', 'passive_income', 'leg_match_bonus', 'withdrawal', 'withdrawal_fee', 'deposit', 'booking_refund') NOT NULL,
`description` TEXT,
`related_booking_id` INT NULL,
`related_user_id` INT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (related_booking_id) REFERENCES bookings(id) ON DELETE SET NULL,
FOREIGN KEY (related_user_id) REFERENCES users(id) ON DELETE SET NULL
)";
run_sql($db, $sqlTransactions, "Table 'transactions' created or already exists.");
// 4. Withdrawals table
$sqlWithdrawals = "CREATE TABLE IF NOT EXISTS `withdrawals` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT NOT NULL,
`amount` DECIMAL(15, 2) NOT NULL,
`status` ENUM('pending', 'approved', 'rejected') NOT NULL DEFAULT 'pending',
`rejection_reason` TEXT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`processed_at` TIMESTAMP NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)";
run_sql($db, $sqlWithdrawals, "Table 'withdrawals' created or already exists.");
run_sql($db, "ALTER TABLE withdrawals MODIFY amount DECIMAL(15, 2) NOT NULL", "Column 'amount' in 'withdrawals' table modified.");
// 5. Leg Milestones table
$sqlLegMilestones = "CREATE TABLE IF NOT EXISTS `leg_milestones` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT NOT NULL,
`leg_user_id` INT NOT NULL, /* The user in the downline whose leg reached the milestone */
`milestone_amount` DECIMAL(15, 2) NOT NULL,
`bonus_amount` DECIMAL(15, 2) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (leg_user_id) REFERENCES users(id) ON DELETE CASCADE
)";
run_sql($db, $sqlLegMilestones, "Table 'leg_milestones' created or already exists.");
// 6. Passive Income Schedule table (now references transactions)
$sqlPassiveIncome = "CREATE TABLE IF NOT EXISTS `passive_income_schedule` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`transaction_id` INT NOT NULL, /* The direct commission transaction */
`user_id` INT NOT NULL,
`amount` DECIMAL(15, 2) NOT NULL,
`payment_date` DATE NOT NULL,
`status` ENUM('pending', 'paid', 'cancelled') NOT NULL DEFAULT 'pending',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)";
run_sql($db, $sqlPassiveIncome, "Table 'passive_income_schedule' created or already exists.");
// 7. Insert/Update Super Admin User
$adminName = 'Super Admin';
$adminEmail = 'admin@example.com';
$adminPassword = 'admin';
$hashedPassword = password_hash($adminPassword, PASSWORD_BCRYPT);
$adminReferralCode = 'ADMIN';
$stmt = $db->prepare("SELECT id FROM users WHERE email = :email");
$stmt->execute([':email' => $adminEmail]);
if ($stmt->rowCount() == 0) {
$sql = "INSERT INTO users (name, email, password, referral_code, `role`) VALUES (:name, :email, :password, :referral_code, 'Super Admin')";
$stmt = $db->prepare($sql);
$stmt->execute([
':name' => $adminName,
':email' => $adminEmail,
':password' => $hashedPassword,
':referral_code' => $adminReferralCode
]);
echo "Super Admin user created successfully.";
} else {
$sql = "UPDATE users SET password = :password, `role` = 'Super Admin' WHERE email = :email";
$stmt = $db->prepare($sql);
$stmt->execute([
':password' => $hashedPassword,
':email' => $adminEmail
]);
echo "Super Admin user updated successfully.";
}
echo "<br>Database setup/update complete.";
} catch (PDOException $e) {
die("DB ERROR: ". $e->getMessage());
}

23
delete_user.php Normal file
View File

@ -0,0 +1,23 @@
<?php
session_start();
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'Super Admin') {
header('Location: login.php');
exit;
}
require_once 'db/config.php';
if (isset($_GET['id'])) {
$user_id = $_GET['id'];
$db = db();
$stmt = $db->prepare('DELETE FROM users WHERE id = ?');
$stmt->execute([$user_id]);
header('Location: admin_dashboard.php');
exit;
} else {
header('Location: admin_dashboard.php');
exit;
}
?>

83
edit_content.php Normal file
View File

@ -0,0 +1,83 @@
<?php
session_start();
if (!isset($_SESSION['user_id']) || ($_SESSION['role'] !== 'Super Admin' && $_SESSION['role'] !== 'Admin')) {
header('Location: login.php');
exit;
}
$content_file = 'content.json';
$content = json_decode(file_get_contents($content_file), true);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Create a backup of the current content file
copy($content_file, $content_file . '.bak');
foreach ($_POST as $key => $value) {
if (array_key_exists($key, $content)) {
$content[$key] = $value;
}
}
file_put_contents($content_file, json_encode($content, JSON_PRETTY_PRINT));
header('Location: edit_content.php?success=true');
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Landing Page Content</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/dashboard.css?v=<?php echo time(); ?>">
</head>
<body>
<div class="sidebar">
<h3 class="text-center p-3">Admin</h3>
<a href="admin_dashboard.php"><i class="bi bi-people-fill me-2"></i> User Management</a>
<a href="edit_content.php" class="active"><i class="bi bi-pencil-square me-2"></i> Edit Content</a>
<a href="index.php" target="_blank"><i class="bi bi-box-arrow-up-right me-2"></i> View Site</a>
<a href="logout.php"><i class="bi bi-box-arrow-left me-2"></i> Logout</a>
</div>
<div class="main-content">
<div class="header">
<h1>Edit Landing Page Content</h1>
</div>
<?php if(isset($_GET['success'])): ?>
<div class="alert alert-success">Content updated successfully!</div>
<?php endif; ?>
<div class="card p-4">
<form action="edit_content.php" method="POST">
<div class="row">
<?php foreach ($content as $key => $value): ?>
<div class="col-md-6">
<div class="mb-3">
<label for="<?php echo $key; ?>" class="form-label"><?php echo ucwords(str_replace('_', ' ', $key)); ?></label>
<?php if(strlen($value) > 100): ?>
<textarea class="form-control" id="<?php echo $key; ?>" name="<?php echo $key; ?>" rows="4"><?php echo htmlspecialchars($value); ?></textarea>
<?php else: ?>
<input type="text" class="form-control" id="<?php echo $key; ?>" name="<?php echo $key; ?>" value="<?php echo htmlspecialchars($value); ?>">
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary">Save Changes</button>
<a href="admin_dashboard.php" class="btn btn-secondary ms-2">Cancel</a>
</div>
</form>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

134
edit_user.php Normal file
View File

@ -0,0 +1,134 @@
<?php
session_start();
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'Super Admin') {
header('Location: login.php');
exit;
}
require_once 'db/config.php';
$user = null;
if (isset($_GET['id'])) {
$user_id = $_GET['id'];
$db = db();
$stmt = $db->prepare('SELECT id, name, email, role, agent_tier, cumulative_bookings, phone, company, notes FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
header('Location: admin_dashboard.php?error=user_not_found');
exit;
}
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$role = $_POST['role'];
$agent_tier = $_POST['agent_tier'];
$phone = $_POST['phone'];
$company = $_POST['company'];
$notes = $_POST['notes'];
$user_id = $_POST['user_id'];
if (empty($name) || empty($email) || empty($role)) {
header('Location: edit_user.php?id=' . $user_id . '&error=empty_fields');
exit;
}
$db = db();
$stmt = $db->prepare('UPDATE users SET name = ?, email = ?, role = ?, agent_tier = ?, phone = ?, company = ?, notes = ? WHERE id = ?');
$stmt->execute([$name, $email, $role, $agent_tier, $phone, $company, $notes, $user_id]);
header('Location: admin_dashboard.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit User</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/dashboard.css?v=<?php echo time(); ?>">
</head>
<body>
<div class="sidebar">
<h3 class="text-center p-3">Admin</h3>
<a href="admin_dashboard.php" class="active"><i class="bi bi-people-fill me-2"></i> User Management</a>
<a href="edit_content.php"><i class="bi bi-pencil-square me-2"></i> Edit Content</a>
<a href="index.php" target="_blank"><i class="bi bi-box-arrow-up-right me-2"></i> View Site</a>
<a href="logout.php"><i class="bi bi-box-arrow-left me-2"></i> Logout</a>
</div>
<div class="main-content">
<div class="header">
<h1>Edit User</h1>
</div>
<div class="card p-4">
<?php if ($user): ?>
<form action="edit_user.php" method="POST">
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($user['name']); ?>" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($user['email']); ?>" required>
</div>
<div class="mb-3">
<label for="phone" class="form-label">Phone</label>
<input type="text" class="form-control" id="phone" name="phone" value="<?php echo htmlspecialchars($user['phone']); ?>">
</div>
<div class="mb-3">
<label for="company" class="form-label">Company</label>
<input type="text" class="form-control" id="company" name="company" value="<?php echo htmlspecialchars($user['company']); ?>">
</div>
<div class="mb-3">
<label for="notes" class="form-label">Notes</label>
<textarea class="form-control" id="notes" name="notes" rows="3"><?php echo htmlspecialchars($user['notes']); ?></textarea>
</div>
<div class="mb-3">
<label for="role" class="form-label">Role</label>
<select class="form-select" id="role" name="role">
<option value="Agent" <?php if ($user['role'] === 'Agent') echo 'selected'; ?>>Agent</option>
<option value="Finance" <?php if ($user['role'] === 'Finance') echo 'selected'; ?>>Finance</option>
<option value="Support" <?php if ($user['role'] === 'Support') echo 'selected'; ?>>Support</option>
<option value="Admin" <?php if ($user['role'] === 'Admin') echo 'selected'; ?>>Admin</option>
<option value="Super Admin" <?php if ($user['role'] === 'Super Admin') echo 'selected'; ?>>Super Admin</option>
</select>
</div>
<div class="mb-3">
<label for="agent_tier" class="form-label">Agent Tier</label>
<select class="form-select" id="agent_tier" name="agent_tier">
<option value="Normal" <?php if ($user['agent_tier'] === 'Normal') echo 'selected'; ?>>Normal</option>
<option value="Silver" <?php if ($user['agent_tier'] === 'Silver') echo 'selected'; ?>>Silver</option>
<option value="Gold" <?php if ($user['agent_tier'] === 'Gold') echo 'selected'; ?>>Gold</option>
<option value="Diamond" <?php if ($user['agent_tier'] === 'Diamond') echo 'selected'; ?>>Diamond</option>
</select>
</div>
<div class="mb-3">
<label for="cumulative_bookings" class="form-label">Cumulative Bookings (INR)</label>
<input type="text" class="form-control" id="cumulative_bookings" name="cumulative_bookings" value="<?php echo htmlspecialchars($user['cumulative_bookings']); ?>" readonly>
</div>
<button type="submit" class="btn btn-primary">Update User</button>
<a href="admin_dashboard.php" class="btn btn-secondary">Cancel</a>
</form>
<?php else: ?>
<div class="alert alert-danger">User not found.</div>
<?php endif; ?>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

168
genealogy.php Normal file
View File

@ -0,0 +1,168 @@
<?php
session_start();
require_once 'auth.php';
require_once 'db/config.php';
if (!is_logged_in()) {
header("Location: login.php");
exit;
}
$db = db();
// Function to recursively fetch the downline tree
function get_downline_tree($userId, $db) {
$tree = [];
$stmt = $db->prepare("SELECT id, name, email, agent_tier FROM users WHERE sponsor_id = :sponsor_id ORDER BY name");
$stmt->execute([':sponsor_id' => $userId]);
$downline = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($downline as $member) {
$member['downline'] = get_downline_tree($member['id'], $db);
$tree[] = $member;
}
return $tree;
}
// Function to recursively display the tree as a nested list
function display_tree_node($node) {
echo '<li>';
echo '<div class="card member-card">';
echo '<div class="card-body">';
echo '<h5>' . htmlspecialchars($node['name']) . '</h5>';
echo '<p class="mb-1"><small>' . htmlspecialchars($node['email']) . '</small></p>';
echo '<span class="badge bg-info text-dark"> ' . htmlspecialchars($node['agent_tier']) . '</span>';
echo '</div>';
echo '</div>';
if (!empty($node['downline'])) {
echo '<ul>';
foreach ($node['downline'] as $child) {
display_tree_node($child);
}
echo '</ul>';
}
echo '</li>';
}
$stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute([':id' => $_SESSION['user_id']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
$genealogy_tree = get_downline_tree($user['id'], $db);
$site_name = 'Kutumbh Infra';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Genealogy Tree - <?php echo htmlspecialchars($site_name); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
<link href="assets/css/dashboard.css" rel="stylesheet">
<style>
.genealogy-tree ul {
padding-left: 20px;
list-style: none;
position: relative;
}
.genealogy-tree ul li {
margin-top: 10px;
position: relative;
}
.genealogy-tree ul li::before {
content: '';
position: absolute;
top: -10px;
left: -20px;
border-left: 1px solid #ddd;
border-bottom: 1px solid #ddd;
width: 20px;
height: 27px;
}
.genealogy-tree > ul > li::before {
border: none;
}
.genealogy-tree ul li:last-child::before {
height: 27px;
}
.member-card {
border-left: 3px solid #0dcaf0;
}
</style>
</head>
<body>
<div class="sidebar">
<a href="index.php" class="logo"><?php echo htmlspecialchars($site_name); ?></a>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link" href="dashboard.php"><i class="bi bi-grid"></i> Dashboard</a></li>
<?php if (is_agent()): ?>
<li class="nav-item"><a class="nav-link" href="submit_booking.php"><i class="bi bi-journal-plus"></i> Submit Booking</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link active" href="genealogy.php"><i class="bi bi-diagram-3"></i> Genealogy Tree</a></li>
<li class="nav-item"><a class="nav-link" href="ledger.php"><i class="bi bi-receipt"></i> Ledger</a></li>
<li class="nav-item"><a class="nav-link" href="withdraw.php"><i class="bi bi-cash-coin"></i> Withdraw</a></li>
<?php if (is_admin() || is_super_admin()): ?>
<li class="nav-item"><hr></li>
<li class="nav-item-header">Admin Menu</li>
<li class="nav-item"><a class="nav-link" href="admin/bookings.php"><i class="bi bi-calendar-check"></i> Manage Bookings</a></li>
<?php endif; ?>
<?php if (is_super_admin()): ?>
<li class="nav-item"><a class="nav-link" href="admin_dashboard.php"><i class="bi bi-people"></i> User Management</a></li>
<li class="nav-item"><a class="nav-link" href="edit_content.php"><i class="bi bi-pencil-square"></i> Edit Content</a></li>
<?php endif; ?>
<li class="nav-item"><hr></li>
<li class="nav-item"><a class="nav-link" href="logout.php"><i class="bi bi-box-arrow-left"></i> Logout</a></li>
</ul>
</div>
<div class="main-content">
<header class="header">
<h1 class="h3 mb-0">Genealogy Tree</h1>
<div class="dropdown">
<a href="#" class="d-block link-dark text-decoration-none dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle fs-4"></i> <span class="d-none d-sm-inline mx-1"><?php echo htmlspecialchars($user['name']); ?></span>
</a>
<ul class="dropdown-menu text-small dropdown-menu-end">
<li><span class="dropdown-item-text"><strong><?php echo htmlspecialchars($user['name']); ?></strong><br><small><?php echo htmlspecialchars($user['role']); ?></small></span></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="logout.php">Sign out</a></li>
</ul>
</div>
</header>
<main class="container-fluid">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Your Downline</h5>
</div>
<div class="card-body">
<div class="genealogy-tree">
<ul>
<?php if (empty($genealogy_tree)): ?>
<p>You have no users in your downline yet.</p>
<?php else: ?>
<?php foreach ($genealogy_tree as $node): ?>
<?php display_tree_node($node); ?>
<?php endforeach; ?>
<?php endif; ?>
</ul>
</div>
</div>
</div>
</main>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

336
index.php
View File

@ -1,150 +1,202 @@
<?php
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
session_start();
$content = json_decode(file_get_contents('content.json'), true);
?>
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New Style</title>
<?php
// Read project preview data from environment
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
?>
<?php if ($projectDescription): ?>
<!-- Meta description -->
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
<!-- Open Graph meta tags -->
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<!-- Twitter meta tags -->
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($content['site_title']); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="assets/css/dashboard.css?v=<?php echo time(); ?>" rel="stylesheet">
</head>
<body>
<main>
<div class="card">
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
<span class="sr-only">Loading…</span>
</div>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
<p class="hint">This page will update automatically as the plan is implemented.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top shadow-sm">
<div class="container">
<a class="navbar-brand" href="#">
<i class="bi bi-buildings"></i>
<?php echo htmlspecialchars($content['site_name']); ?>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto align-items-center">
<li class="nav-item"><a class="nav-link nav-link-custom" href="#about">About</a></li>
<li class="nav-item"><a class="nav-link nav-link-custom" href="#features">Features</a></li>
<li class="nav-item"><a class="nav-link nav-link-custom" href="#contact">Contact</a></li>
<?php if (isset($_SESSION['user_id'])): ?>
<li class="nav-item"><a class="nav-link" href="dashboard.php">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="logout.php">Logout</a></li>
<?php else: ?>
<li class="nav-item"><a class="btn btn-outline-secondary me-2" href="login.php">Login</a></li>
<li class="nav-item"><a class="btn btn-primary" href="register.php">Register</a></li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
<header class="hero-section">
<div class="container">
<h1><?php echo htmlspecialchars($content['hero_title']); ?></h1>
<p class="lead"><?php echo htmlspecialchars($content['hero_subtitle']); ?></p>
<?php if (!isset($_SESSION['user_id'])) : ?>
<a href="register.php" class="btn btn-light btn-lg">Get Started Today</a>
<?php endif; ?>
</div>
</header>
<main>
<section id="about" class="section">
<div class="container">
<div class="row align-items-center">
<div class="col-md-6">
<h2 class="section-title text-start"><?php echo htmlspecialchars($content['about_us_title']); ?></h2>
<p><?php echo htmlspecialchars($content['about_us_content_1']); ?></p>
<p><?php echo htmlspecialchars($content['about_us_content_2']); ?></p>
</div>
<div class="col-md-6 text-center">
<img src="assets/images/about-us.jpg" class="img-fluid rounded shadow" alt="About Us Image">
</div>
</div>
</div>
</section>
<section id="features" class="section bg-light">
<div class="container">
<h2 class="section-title"><?php echo htmlspecialchars($content['features_title']); ?></h2>
<div class="row g-4">
<div class="col-md-4">
<div class="feature-card">
<i class="bi bi-graph-up-arrow feature-icon"></i>
<h3><?php echo htmlspecialchars($content['feature_1_title']); ?></h3>
<p><?php echo htmlspecialchars($content['feature_1_content']); ?></p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i class="bi bi-people-fill feature-icon"></i>
<h3><?php echo htmlspecialchars($content['feature_2_title']); ?></h3>
<p><?php echo htmlspecialchars($content['feature_2_content']); ?></p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i class="bi bi-headset feature-icon"></i>
<h3><?php echo htmlspecialchars($content['feature_3_title']); ?></h3>
<p><?php echo htmlspecialchars($content['feature_3_content']); ?></p>
</div>
</div>
</div>
</div>
</section>
<section id="contact" class="section">
<div class="container">
<h2 class="section-title"><?php echo htmlspecialchars($content['contact_us_title']); ?></h2>
<p class="lead mb-5"><?php echo htmlspecialchars($content['contact_us_content']); ?></p>
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="alert alert-info" role="alert">
For testing purposes, emails will be sent to <strong><?php echo htmlspecialchars(getenv('MAIL_TO') ?: getenv('MAIL_FROM')); ?></strong>. You can ask me to change this for you.
</div>
<form action="submit_contact.php" method="POST">
<div class="mb-3">
<input type="text" class="form-control" name="name" placeholder="Your Name" required>
</div>
<div class="mb-3">
<input type="email" class="form-control" name="email" placeholder="Your Email" required>
</div>
<div class="mb-3">
<textarea class="form-control" name="message" rows="5" placeholder="Your Message" required></textarea>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary btn-lg">Send Message</button>
</div>
</form>
</div>
</div>
</div>
</section>
</main>
<footer class="text-center p-4 bg-dark text-white">
<div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> <?php echo htmlspecialchars($content['site_name']); ?>. All Rights Reserved.</p>
</div>
</footer>
<button class="chat-open-button" onclick="openChat()">
<i class="bi bi-chat-dots-fill"></i>
</button>
<div class="chat-popup" id="chatPopup">
<div class="chat-header">
<span>AI Assistant</span>
<button type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeChat()"></button>
</div>
<div class="chat-messages" id="chatMessages">
<div class="chat-message bot-message">Hi! How can I help you today?</div>
</div>
<div class="chat-input">
<input type="text" id="userInput" class="form-control" placeholder="Type a message..." onkeydown="if(event.keyCode == 13) sendMessage()">
<button class="btn btn-primary" onclick="sendMessage()"><i class="bi bi-send-fill"></i></button>
</div>
</div>
</main>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC)
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
function openChat() {
document.getElementById("chatPopup").style.display = "flex";
document.querySelector(".chat-open-button").style.display = "none";
}
function closeChat() {
document.getElementById("chatPopup").style.display = "none";
document.querySelector(".chat-open-button").style.display = "block";
}
function sendMessage() {
const userInput = document.getElementById("userInput");
const message = userInput.value;
if (message.trim() === "") return;
appendMessage(message, "user");
userInput.value = "";
fetch("ai_agent.php", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ message: message }),
})
.then(response => response.json())
.then(data => {
appendMessage(data.reply, "bot");
})
.catch(error => {
console.error("Error:", error);
appendMessage("Sorry, something went wrong.", "bot");
});
}
function appendMessage(message, sender) {
const chatMessages = document.getElementById("chatMessages");
const messageElement = document.createElement("div");
messageElement.classList.add("chat-message", sender + "-message");
messageElement.innerText = message;
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
</script>
</body>
</html>
</html>

156
ledger.php Normal file
View File

@ -0,0 +1,156 @@
<?php
session_start();
require_once 'auth.php';
require_once 'db/config.php';
if (!is_logged_in()) {
header("Location: login.php");
exit;
}
$db = db();
// 1. Fetch user data
$stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute([':id' => $_SESSION['user_id']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// 2. Pagination Logic
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$records_per_page = 25;
$offset = ($page - 1) * $records_per_page;
// Get total number of transactions for the user
$total_stmt = $db->prepare("SELECT COUNT(*) FROM transactions WHERE user_id = :user_id");
$total_stmt->execute([':user_id' => $user['id']]);
$total_records = $total_stmt->fetchColumn();
$total_pages = ceil($total_records / $records_per_page);
// 3. Fetch Transactions for the current page
$stmt = $db->prepare("SELECT * FROM transactions WHERE user_id = :user_id ORDER BY created_at DESC LIMIT :limit OFFSET :offset");
$stmt->bindValue(':user_id', $user['id'], PDO::PARAM_INT);
$stmt->bindValue(':limit', $records_per_page, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$transactions = $stmt->fetchAll(PDO::FETCH_ASSOC);
$site_name = 'Kutumbh Infra';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transaction Ledger - <?php echo htmlspecialchars($site_name); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
<link href="assets/css/dashboard.css" rel="stylesheet">
</head>
<body>
<div class="sidebar">
<a href="index.php" class="logo"><?php echo htmlspecialchars($site_name); ?></a>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link" href="dashboard.php"><i class="bi bi-grid"></i> Dashboard</a></li>
<?php if (is_agent()): ?>
<li class="nav-item"><a class="nav-link" href="submit_booking.php"><i class="bi bi-journal-plus"></i> Submit Booking</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="genealogy.php"><i class="bi bi-diagram-3"></i> Genealogy Tree</a></li>
<li class="nav-item"><a class="nav-link active" href="ledger.php"><i class="bi bi-receipt"></i> Ledger</a></li>
<li class="nav-item"><a class="nav-link" href="withdraw.php"><i class="bi bi-cash-coin"></i> Withdraw</a></li>
<?php if (is_admin() || is_super_admin()): ?>
<li class="nav-item"><hr></li>
<li class="nav-item-header">Admin Menu</li>
<li class="nav-item"><a class="nav-link" href="admin/bookings.php"><i class="bi bi-calendar-check"></i> Manage Bookings</a></li>
<?php endif; ?>
<?php if (is_super_admin()): ?>
<li class="nav-item"><a class="nav-link" href="admin_dashboard.php"><i class="bi bi-people"></i> User Management</a></li>
<li class="nav-item"><a class="nav-link" href="edit_content.php"><i class="bi bi-pencil-square"></i> Edit Content</a></li>
<?php endif; ?>
<li class="nav-item"><hr></li>
<li class="nav-item"><a class="nav-link" href="logout.php"><i class="bi bi-box-arrow-left"></i> Logout</a></li>
</ul>
</div>
<div class="main-content">
<header class="header">
<h1 class="h3 mb-0">Transaction Ledger</h1>
<div class="dropdown">
<a href="#" class="d-block link-dark text-decoration-none dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle fs-4"></i> <span class="d-none d-sm-inline mx-1"><?php echo htmlspecialchars($user['name']); ?></span>
</a>
<ul class="dropdown-menu text-small dropdown-menu-end">
<li><span class="dropdown-item-text"><strong><?php echo htmlspecialchars($user['name']); ?></strong><br><small><?php echo htmlspecialchars($user['role']); ?></small></span></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="logout.php">Sign out</a></li>
</ul>
</div>
</header>
<main class="container-fluid">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Your Transactions</h5>
<div class="text-end">
<h6 class="mb-0">Wallet Balance</h6>
<span class="fs-5"><?php echo number_format($user['wallet_balance'], 2); ?></span>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Date</th>
<th>Type</th>
<th>Amount</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<?php if (empty($transactions)): ?>
<tr><td colspan="4" class="text-center">No transactions found.</td></tr>
<?php else: ?>
<?php foreach ($transactions as $tx): ?>
<tr>
<td><?php echo date('d M Y, H:i', strtotime($tx['created_at'])); ?></td>
<td><span class="badge bg-secondary"><?php echo ucwords(str_replace('_', ' ', $tx['type'])); ?></span></td>
<td class="<?php echo $tx['amount'] >= 0 ? 'text-success' : 'text-danger'; ?> fw-bold">
<?php echo ($tx['amount'] >= 0 ? '+' : '-') . ' ₹' . number_format(abs($tx['amount']), 2); ?>
</td>
<td><?php echo htmlspecialchars($tx['description']); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<!-- Pagination Controls -->
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<?php if ($page > 1): ?>
<li class="page-item"><a class="page-link" href="?page=<?php echo $page - 1; ?>">Previous</a></li>
<?php endif; ?>
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<li class="page-item <?php echo $i == $page ? 'active' : ''; ?>"><a class="page-link" href="?page=<?php echo $i; ?>"><?php echo $i; ?></a></li>
<?php endfor; ?>
<?php if ($page < $total_pages): ?>
<li class="page-item"><a class="page-link" href="?page=<?php echo $page + 1; ?>">Next</a></li>
<?php endif; ?>
</ul>
</nav>
</div>
</div>
</main>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

75
login.php Normal file
View File

@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - Your Brand</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="assets/css/auth.css" rel="stylesheet">
</head>
<body class="auth-wrapper">
<?php
require_once 'auth.php';
$error = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$email = $_POST['email'];
$password = $_POST['password'];
if (login($email, $password)) {
if ($_SESSION['user_type'] === 'Admin') {
header("Location: admin_dashboard.php");
} else {
header("Location: dashboard.php");
}
exit;
} else {
$error = 'Invalid email or password.';
}
}
?>
<div class="auth-container">
<div class="auth-branding-section">
<a href="index.php" class="text-white text-decoration-none h1"> <i class="bi bi-buildings"></i> <?php echo htmlspecialchars($content['site_name']); ?></a>
<p class="lead mt-3">Log in to access your dashboard and manage your network.</p>
</div>
<div class="auth-form-section">
<div class="text-center mb-5">
<h2>Sign In</h2>
<p class="text-muted">Enter your credentials to continue.</p>
</div>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<form method="POST">
<div class="mb-4">
<label for="email" class="form-label">Email Address</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-envelope-fill"></i></span>
<input type="email" name="email" id="email" class="form-control form-control-lg" placeholder="e.g., name@example.com" required>
</div>
</div>
<div class="mb-4">
<div class="d-flex justify-content-between">
<label for="password" class="form-label">Password</label>
<a href="#" class="text-decoration-none">Forgot Password?</a>
</div>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-lock-fill"></i></span>
<input type="password" name="password" id="password" class="form-control form-control-lg" placeholder="Your password" required>
</div>
</div>
<div class="d-grid mb-4">
<button type="submit" class="btn btn-primary btn-lg">Sign In</button>
</div>
<p class="text-center">Don't have an account? <a href="register.php">Sign up now</a>.</p>
</form>
<div class="text-center mt-5">
<a href="index.php" class="text-muted text-decoration-none"><i class="bi bi-arrow-left"></i> Back to Homepage</a>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

5
logout.php Normal file
View File

@ -0,0 +1,5 @@
<?php
session_start();
session_destroy();
header("Location: login.php");
exit;

255
mlm_logic.php Normal file
View File

@ -0,0 +1,255 @@
<?php
require_once __DIR__ . '/db/config.php';
/**
* Fetches the upline for a given user.
*
* @param int $userId The ID of the user.
* @param int $levels The number of levels to fetch.
* @return array The upline users.
*/
function get_upline($userId, $levels = 10) {
$upline = [];
$currentUser = $userId;
for ($i = 0; $i < $levels; $i++) {
$db = db();
$stmt = $db->prepare("SELECT sponsor_id FROM users WHERE id = :id");
$stmt->execute([':id' => $currentUser]);
$sponsor = $stmt->fetch(PDO::FETCH_ASSOC);
if ($sponsor && $sponsor['sponsor_id']) {
$upline[] = $sponsor['sponsor_id'];
$currentUser = $sponsor['sponsor_id'];
} else {
break;
}
}
return $upline;
}
/**
* Calculates and distributes commissions for a given booking.
*
* @param int $bookingId The ID of the booking.
*/
function calculate_commissions($bookingId) {
$db = db();
$db->beginTransaction();
try {
// 1. Get booking details
$stmt = $db->prepare("SELECT user_id, amount FROM bookings WHERE id = :booking_id AND status = 'approved'");
$stmt->execute([':booking_id' => $bookingId]);
$booking = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$booking) {
throw new Exception("Booking not found or not approved.");
}
$bookingAmount = $booking['amount'];
$bookingUserId = $booking['user_id'];
// 2. Get upline
$upline = get_upline($bookingUserId, 10);
if (empty($upline)) {
// No upline, nothing to do
$db->commit();
return;
}
// 3. Direct Commission (Level 10)
$directCommission = $bookingAmount * 0.10;
$directSponsorId = $upline[0];
// Insert transaction for direct commission
$stmt = $db->prepare(
"INSERT INTO transactions (user_id, amount, type, description, related_booking_id, related_user_id) VALUES (:user_id, :amount, 'commission_direct', :description, :booking_id, :related_user_id)"
);
$stmt->execute([
':user_id' => $directSponsorId,
':amount' => $directCommission,
':description' => 'Direct commission for booking #' . $bookingId,
':booking_id' => $bookingId,
':related_user_id' => $bookingUserId
]);
$directCommissionTransactionId = $db->lastInsertId();
// Schedule passive income for the sponsor
schedule_passive_income($directCommissionTransactionId, $directSponsorId, $directCommission, $db);
// Update sponsor's wallet and income
$stmt = $db->prepare("UPDATE users SET wallet_balance = wallet_balance + :amount, total_direct_income = total_direct_income + :amount WHERE id = :user_id");
$stmt->execute([':amount' => $directCommission, ':user_id' => $directSponsorId]);
// 4. Team Commissions (Levels 9 down to 1)
$previousLevelCommission = $directCommission;
for ($i = 1; $i < count($upline); $i++) {
$teamCommission = $previousLevelCommission * 0.50;
$uplineMemberId = $upline[$i];
// Insert transaction for team commission
$stmt = $db->prepare(
"INSERT INTO transactions (user_id, amount, type, description, related_booking_id, related_user_id) VALUES (:user_id, :amount, 'commission_team', :description, :booking_id, :related_user_id)"
);
$stmt->execute([
':user_id' => $uplineMemberId,
':amount' => $teamCommission,
':description' => 'Team commission (Level ' . (10 - ($i + 1) + 1) . ') for booking #' . $bookingId,
':booking_id' => $bookingId,
':related_user_id' => $bookingUserId
]);
// Update user's wallet and income
$stmt = $db->prepare("UPDATE users SET wallet_balance = wallet_balance + :amount, total_team_income = total_team_income + :amount WHERE id = :user_id");
$stmt->execute([':amount' => $teamCommission, ':user_id' => $uplineMemberId]);
$previousLevelCommission = $teamCommission;
}
// 5. Calculate Leg Match Bonus
calculate_leg_match_bonus($bookingUserId, $db);
$db->commit();
echo "Commissions calculated and distributed successfully for booking #$bookingId.";
} catch (Exception $e) {
$db->rollBack();
error_log("Commission calculation failed for booking #$bookingId: " . $e->getMessage());
// Handle or log the error appropriately
}
}
/**
* Calculates and distributes leg match bonuses.
*/
/**
* Recursively calculates the total booking volume for a given user and their entire downline.
*
* @param int $userId The ID of the user at the top of the leg.
* @param PDO $db The database connection.
* @return float The total volume of the leg.
*/
function get_leg_volume($userId, $db) {
$totalVolume = 0.0;
// Get the user's own contribution
$stmt = $db->prepare("SELECT cumulative_bookings FROM users WHERE id = :user_id");
$stmt->execute([':user_id' => $userId]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
$totalVolume += $user['cumulative_bookings'];
}
// Get all directly sponsored users
$stmt = $db->prepare("SELECT id FROM users WHERE sponsor_id = :sponsor_id");
$stmt->execute([':sponsor_id' => $userId]);
$downline = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($downline as $downlineUser) {
$totalVolume += get_leg_volume($downlineUser['id'], $db);
}
return $totalVolume;
}
/**
* Calculates and distributes leg match bonuses.
*
* @param int $bookingUserId The user who made the original booking.
* @param PDO $db The database connection.
*/
function calculate_leg_match_bonus($bookingUserId, $db) {
// A leg match bonus is paid to the SPONSOR of the user who made the booking,
// based on the performance of their OTHER legs.
// The spec is "5% leg-match paid to user for every INR 10,00,000 leg milestone".
// This implies we check the sponsor's legs.
// Get the sponsor of the person who made the booking
$stmt = $db->prepare("SELECT sponsor_id FROM users WHERE id = :id");
$stmt->execute([':id' => $bookingUserId]);
$sponsor = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$sponsor || !$sponsor['sponsor_id']) {
return; // No sponsor, no bonus to calculate
}
$sponsorId = $sponsor['sponsor_id'];
// Get all the direct downlines of the SPONSOR (these are the legs)
$stmt = $db->prepare("SELECT id FROM users WHERE sponsor_id = :sponsor_id");
$stmt->execute([':sponsor_id' => $sponsorId]);
$legs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$milestoneAmount = 1000000.00;
$bonusPercentage = 0.05;
$bonusAmount = $milestoneAmount * $bonusPercentage;
foreach ($legs as $leg) {
$legUserId = $leg['id'];
$legVolume = get_leg_volume($legUserId, $db);
// Find out how many milestones this leg has already been paid for
$stmt = $db->prepare("SELECT COUNT(*) as count FROM leg_milestones WHERE user_id = :user_id AND leg_user_id = :leg_user_id");
$stmt->execute([':user_id' => $sponsorId, ':leg_user_id' => $legUserId]);
$paidMilestonesCount = $stmt->fetch(PDO::FETCH_ASSOC)['count'];
$achievedMilestones = floor($legVolume / $milestoneAmount);
if ($achievedMilestones > $paidMilestonesCount) {
$newMilestones = $achievedMilestones - $paidMilestonesCount;
for ($i = 0; $i < $newMilestones; $i++) {
$currentMilestoneNumber = $paidMilestonesCount + $i + 1;
$currentMilestoneValue = $currentMilestoneNumber * $milestoneAmount;
// 1. Pay the bonus
$stmt = $db->prepare(
"INSERT INTO transactions (user_id, amount, type, description, related_user_id) VALUES (:user_id, :amount, 'leg_match_bonus', :description, :related_user_id)"
);
$stmt->execute([
':user_id' => $sponsorId,
':amount' => $bonusAmount,
':description' => "Leg match bonus for leg of user #$legUserId reaching milestone ₹" . number_format($currentMilestoneValue),
':related_user_id' => $legUserId
]);
// 2. Update wallet
$stmt = $db->prepare("UPDATE users SET wallet_balance = wallet_balance + :amount, total_leg_match_income = total_leg_match_income + :amount WHERE id = :user_id");
$stmt->execute([':amount' => $bonusAmount, ':user_id' => $sponsorId]);
// 3. Record the milestone payment
$stmt = $db->prepare("INSERT INTO leg_milestones (user_id, leg_user_id, milestone_amount, bonus_amount) VALUES (:user_id, :leg_user_id, :milestone_amount, :bonus_amount)");
$stmt->execute([
':user_id' => $sponsorId,
':leg_user_id' => $legUserId,
':milestone_amount' => $currentMilestoneValue,
':bonus_amount' => $bonusAmount
]);
}
}
}
}
/**
* Schedules passive income payments.
*/
function schedule_passive_income($directCommissionTransactionId, $userId, $directCommissionAmount, $db) {
$passiveIncomeAmount = $directCommissionAmount * 0.005;
$startDate = new DateTime();
for ($i = 1; $i <= 12; $i++) {
$paymentDate = clone $startDate;
$paymentDate->add(new DateInterval("P{$i}M"));
$stmt = $db->prepare(
"INSERT INTO passive_income_schedule (transaction_id, user_id, amount, payment_date, status) VALUES (:transaction_id, :user_id, :amount, :payment_date, 'pending')"
);
$stmt->execute([
':transaction_id' => $directCommissionTransactionId,
':user_id' => $userId,
':amount' => $passiveIncomeAmount,
':payment_date' => $paymentDate->format('Y-m-d')
]);
}
}

86
register.php Normal file
View File

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register - Your Brand</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="assets/css/auth.css" rel="stylesheet">
</head>
<body class="auth-wrapper">
<?php
require_once 'auth.php';
$error = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];
$sponsor_code = $_POST['sponsor_code'] ?? '';
$result = register($name, $email, $password, $sponsor_code);
if ($result === true) {
header("Location: login.php?registration=success");
exit;
} else {
$error = $result;
}
}
?>
<div class="auth-container">
<div class="auth-branding-section">
<a href="index.php" class="text-white text-decoration-none h1"> <i class="bi bi-buildings"></i> <?php echo htmlspecialchars($content['site_name']); ?></a>
<p class="lead mt-3">Join our network and start your journey with us today.</p>
</div>
<div class="auth-form-section">
<div class="text-center mb-5">
<h2>Create an Account</h2>
<p class="text-muted">Create a new account to get started.</p>
</div>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<form method="POST">
<div class="mb-3">
<label for="name" class="form-label">Full Name</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-person-fill"></i></span>
<input type="text" name="name" id="name" class="form-control form-control-lg" placeholder="e.g., John Doe" required>
</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email Address</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-envelope-fill"></i></span>
<input type="email" name="email" id="email" class="form-control form-control-lg" placeholder="e.g., name@example.com" required>
</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-lock-fill"></i></span>
<input type="password" name="password" id="password" class="form-control form-control-lg" placeholder="Create a strong password" required>
</div>
</div>
<div class="mb-4">
<label for="sponsor_code" class="form-label">Sponsor Code (Optional)</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-person-plus-fill"></i></span>
<input type="text" name="sponsor_code" id="sponsor_code" class="form-control form-control-lg" placeholder="Enter your sponsor's code">
</div>
</div>
<div class="d-grid mb-4">
<button type="submit" class="btn btn-primary btn-lg">Create Account</button>
</div>
<p class="text-center">Already have an account? <a href="login.php">Sign in</a>.</p>
</form>
<div class="text-center mt-5">
<a href="index.php" class="text-muted text-decoration-none"><i class="bi bi-arrow-left"></i> Back to Homepage</a>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

111
submit_booking.php Normal file
View File

@ -0,0 +1,111 @@
<?php
session_start();
require_once 'auth.php';
require_once 'db/config.php';
// 1. Role-Based Access Control
if (!is_logged_in() || !is_agent()) {
header('Location: login.php');
exit;
}
$message = '';
$error = '';
// 2. Form Processing
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$plotId = $_POST['plot_id'] ?? '';
$amount = $_POST['amount'] ?? '';
$bookingDate = $_POST['booking_date'] ?? '';
$proofDocument = $_FILES['proof_document'] ?? null;
// Basic validation
if (empty($plotId) || empty($amount) || empty($bookingDate) || $proofDocument['error'] !== UPLOAD_ERR_OK) {
$error = 'All fields and a valid proof document are required.';
} else {
$uploadDir = 'uploads/';
$uploadFile = $uploadDir . basename($proofDocument['name']);
$fileType = strtolower(pathinfo($uploadFile, PATHINFO_EXTENSION));
// Check if file is a valid type (e.g., pdf, jpg, png)
$allowedTypes = ['pdf', 'jpg', 'jpeg', 'png'];
if (!in_array($fileType, $allowedTypes)) {
$error = 'Invalid file type. Only PDF, JPG, and PNG are allowed.';
} elseif (move_uploaded_file($proofDocument['tmp_name'], $uploadFile)) {
// File uploaded successfully, insert into database
$db = db();
$stmt = $db->prepare(
"INSERT INTO bookings (user_id, plot_id, amount, booking_date, proof_document, status) VALUES (:user_id, :plot_id, :amount, :booking_date, :proof_document, 'pending')"
);
try {
$stmt->execute([
':user_id' => $_SESSION['user_id'],
':plot_id' => $plotId,
':amount' => $amount,
':booking_date' => $bookingDate,
':proof_document' => $uploadFile
]);
$message = 'Booking submitted successfully! It is now pending approval.';
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
}
} else {
$error = 'Failed to upload proof document.';
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Submit Booking</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-8 offset-md-2">
<div class="card">
<div class="card-header">
<h2>Submit a New Booking</h2>
<p>Fill out the form below to submit a new booking for approval.</p>
</div>
<div class="card-body">
<?php if ($message): ?>
<div class="alert alert-success"><?php echo htmlspecialchars($message); ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<form action="submit_booking.php" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="plot_id">Plot ID</label>
<input type="text" class="form-control" id="plot_id" name="plot_id" required>
</div>
<div class="form-group">
<label for="amount">Booking Amount (INR)</label>
<input type="number" class="form-control" id="amount" name="amount" step="0.01" required>
</div>
<div class="form-group">
<label for="booking_date">Booking Date</label>
<input type="date" class="form-control" id="booking_date" name="booking_date" required>
</div>
<div class="form-group">
<label for="proof_document">Proof of Booking (PDF, JPG, PNG)</label>
<input type="file" class="form-control-file" id="proof_document" name="proof_document" required>
</div>
<button type="submit" class="btn btn-primary">Submit for Approval</button>
<a href="dashboard.php" class="btn btn-secondary">Back to Dashboard</a>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

43
submit_contact.php Normal file
View File

@ -0,0 +1,43 @@
<?php
session_start();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Get form data
$name = strip_tags(trim($_POST["name"]));
$email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$message = strip_tags(trim($_POST["message"]));
// Validate form data
if (empty($name) || empty($message) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Redirect back to the form with an error message
header("Location: index.php?status=error#contact");
exit;
}
// Include the MailService
require_once __DIR__ . '/mail/MailService.php';
// Set the recipient email address from environment variables
$to = getenv('MAIL_TO') ?: getenv('MAIL_FROM');
// Set the subject
$subject = "New contact from $name";
// Send the email
$result = MailService::sendContactMessage($name, $email, $message, $to, $subject);
if ($result['success']) {
// Redirect to a success page
header("Location: contact_success.php");
} else {
// Redirect back to the form with an error message
header("Location: contact_error.php");
}
} else {
// If not a POST request, redirect to the homepage
header("Location: index.php");
exit;
}
?>

149
withdraw.php Normal file
View File

@ -0,0 +1,149 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
require_once 'db/config.php';
$db = db();
$user_id = $_SESSION['user_id'];
$message = '';
$error = '';
// Fetch wallet balance
$stmt = $db->prepare("SELECT wallet_balance FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$wallet_balance = $stmt->fetchColumn();
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['amount'])) {
$amount = filter_input(INPUT_POST, 'amount', FILTER_VALIDATE_FLOAT);
if ($amount === false || $amount <= 0) {
$error = 'Please enter a valid withdrawal amount.';
} elseif ($amount > $wallet_balance) {
$error = 'Withdrawal amount cannot exceed your wallet balance.';
} else {
try {
$db->beginTransaction();
// 1. Insert into withdrawals table
$stmt = $db->prepare("INSERT INTO withdrawals (user_id, amount) VALUES (?, ?)");
$stmt->execute([$user_id, $amount]);
$withdrawal_id = $db->lastInsertId();
// 2. Deduct from user's wallet
$stmt = $db->prepare("UPDATE users SET wallet_balance = wallet_balance - ? WHERE id = ?");
$stmt->execute([$amount, $user_id]);
// 3. Record the transaction
$stmt = $db->prepare("INSERT INTO transactions (user_id, amount, type, description, related_withdrawal_id) VALUES (?, ?, 'withdrawal_request', 'Withdrawal request initiated', ?)");
$stmt->execute([$user_id, -$amount, $withdrawal_id]);
$db->commit();
$message = 'Your withdrawal request has been submitted successfully. It will be processed shortly.';
// Refresh wallet balance
$wallet_balance -= $amount;
} catch (PDOException $e) {
$db->rollBack();
$error = 'An error occurred. Please try again.';
// For debugging: error_log($e->getMessage());
}
}
}
// Fetch recent withdrawals
$stmt = $db->prepare("SELECT * FROM withdrawals WHERE user_id = ? ORDER BY created_at DESC LIMIT 10");
$stmt->execute([$user_id]);
$withdrawals = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Request Withdrawal</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<div class="container mt-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Request a Withdrawal</h2>
<a href="dashboard.php" class="btn btn-secondary">Back to Dashboard</a>
</div>
<?php if ($message): ?>
<div class="alert alert-success"><?php echo $message; ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<div class="row">
<div class="col-md-6">
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Available Balance</h5>
<p class="card-text fs-3"><?php echo number_format($wallet_balance, 2); ?></p>
<form method="POST" action="withdraw.php">
<div class="mb-3">
<label for="amount" class="form-label">Withdrawal Amount</label>
<div class="input-group">
<span class="input-group-text"></span>
<input type="number" step="0.01" class="form-control" id="amount" name="amount" placeholder="Enter amount" required>
</div>
</div>
<button type="submit" class="btn btn-primary w-100">Submit Request</button>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
Recent Withdrawal History
</div>
<div class="card-body">
<table class="table table-sm">
<thead>
<tr>
<th>Date</th>
<th>Amount</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php if (empty($withdrawals)): ?>
<tr><td colspan="3" class="text-center">No recent withdrawals.</td></tr>
<?php else: ?>
<?php foreach ($withdrawals as $w): ?>
<tr>
<td><?php echo date('d M Y', strtotime($w['created_at'])); ?></td>
<td><?php echo number_format($w['amount'], 2); ?></td>
<td>
<span class="badge bg-<?php
switch ($w['status']) {
case 'pending': echo 'warning'; break;
case 'approved': echo 'success'; break;
case 'rejected': echo 'danger'; break;
}
?>"><?php echo ucfirst($w['status']); ?></span>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>