From 496d2ec7e5ecdbf22b8978b8b65734e1b853178a Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 5 Dec 2025 06:45:47 +0000 Subject: [PATCH] 1.0 --- admin_users.php | 419 ++++++++++++++++++++++++++++++++++++++++++ assets/css/custom.css | 31 ++++ auth.php | 51 +++++ create_order.php | 119 ++++++++++++ db/config.php | 15 +- db/setup.php | 41 +++++ index.php | 294 ++++++++++++++--------------- login.php | 63 +++++++ logout.php | 6 + partials/footer.php | 9 + partials/header.php | 56 ++++++ 11 files changed, 954 insertions(+), 150 deletions(-) create mode 100644 admin_users.php create mode 100644 assets/css/custom.css create mode 100644 auth.php create mode 100644 create_order.php create mode 100644 db/setup.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 partials/footer.php create mode 100644 partials/header.php diff --git a/admin_users.php b/admin_users.php new file mode 100644 index 0000000..5ea9376 --- /dev/null +++ b/admin_users.php @@ -0,0 +1,419 @@ +prepare("DELETE FROM users WHERE id = ?"); + $stmt->execute([$user_id_to_delete]); + $_SESSION['success_message'] = 'User deleted successfully!'; + } catch (PDOException $e) { + $_SESSION['error_message'] = 'Error deleting user: ' . htmlspecialchars($e->getMessage()); + } + } else { + $_SESSION['error_message'] = 'Invalid user ID or cannot delete your own account.'; + } + header('Location: admin_users.php'); + exit(); +} + +$pageTitle = "Admin | User Management"; +require_once __DIR__ . '/partials/header.php'; +?> + +
+

User Management

+ + +
+
+ Existing Users +
+
+ query("SELECT id, name, email, role, created_at FROM users ORDER BY created_at DESC"); + $users = $stmt->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + echo '
Error fetching users: ' . htmlspecialchars($e->getMessage()) . '
'; + } + ?> + +

No users found.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
IDNameEmailRoleCreated AtActions
+ Edit + Delete +
+
+ +
+ +
+ +
+ + + +
+ +
+ + prepare("SELECT id, name, email, role FROM users WHERE id = ?"); + + $stmt->execute([$edit_user_id]); + + $edit_user = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($edit_user) { + + $name = $edit_user['name']; + + $email = $edit_user['email']; + + $role = $edit_user['role']; + + } else { + + $_SESSION['error_message'] = 'User not found.'; + + header('Location: admin_users.php'); + + exit(); + + } + + } catch (PDOException $e) { + + $_SESSION['error_message'] = 'Error fetching user for edit: ' . htmlspecialchars($e->getMessage()); + + header('Location: admin_users.php'); + + exit(); + + } + + } + + } + + + + // Handle form submission for Add or Edit + + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + + if (isset($_POST['add_user']) || isset($_POST['edit_user'])) { + + $name = trim($_POST['name']); + + $email = trim($_POST['email']); + + $role = $_POST['role']; + + $password = isset($_POST['password']) ? $_POST['password'] : ''; + + $confirm_password = isset($_POST['confirm_password']) ? $_POST['confirm_password'] : ''; + + + + $current_user_id = isset($_POST['user_id']) ? filter_var($_POST['user_id'], FILTER_VALIDATE_INT) : null; + + + + if (empty($name)) { + + $errors[] = 'Name is required.'; + + } + + if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) { + + $errors[] = 'Valid email is required.'; + + } + + if (empty($role)) { + + $errors[] = 'Role is required.'; + + } + + + + if (isset($_POST['add_user'])) { // For adding new user + + if (empty($password)) { + + $errors[] = 'Password is required.'; + + } + + if ($password !== $confirm_password) { + + $errors[] = 'Passwords do not match.'; + + } + + } else if (isset($_POST['edit_user'])) { // For editing existing user + + if (!empty($password) && $password !== $confirm_password) { + + $errors[] = 'Passwords do not match.'; + + } + + } + + + + if (empty($errors)) { + + try { + + if (isset($_POST['add_user'])) { + + $hashed_password = password_hash($password, PASSWORD_DEFAULT); + + $stmt = db()->prepare("INSERT INTO users (name, email, password, role) VALUES (?, ?, ?, ?)"); + + $stmt->execute([$name, $email, $hashed_password, $role]); + + $_SESSION['success_message'] = 'User added successfully!'; + + } else if (isset($_POST['edit_user'])) { + + $sql = "UPDATE users SET name = ?, email = ?, role = ?"; + + $params = [$name, $email, $role]; + + if (!empty($password)) { + + $hashed_password = password_hash($password, PASSWORD_DEFAULT); + + $sql .= ", password = ?"; + + $params[] = $hashed_password; + + } + + $sql .= " WHERE id = ?"; + + $params[] = $current_user_id; + + + + $stmt = db()->prepare($sql); + + $stmt->execute($params); + + $_SESSION['success_message'] = 'User updated successfully!'; + + } + + header('Location: admin_users.php'); + + exit(); + + } catch (PDOException $e) { + + if ($e->getCode() === '23000') { // Duplicate entry + + $errors[] = 'User with this email already exists.'; + + } else { + + $errors[] = 'Error processing user: ' . htmlspecialchars($e->getMessage()); + + } + + } + + } + + } + + } + + ?> + + + + + +
+ + + +

+ + + +
+ + + + + + + +
+ + + +
+ + + + + + + + + +
+ + + +
+ + + + + + + +
+ + + + + + + +
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + > + +
+ +
+ + + + > + +
+ +
+ + + + + +
+ + + + + + Cancel + + + + + + + +
+ +
+
+ + \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..61f1951 --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,31 @@ +body { + font-family: 'Inter', sans-serif; +} + +.bg-light-gray { + background-color: #F8F9FA; +} + +.btn-primary { + background-color: #F97316; + border-color: #F97316; +} + +.btn-primary:hover, .btn-primary:focus, .btn-primary:active { + background-color: #EA580C; + border-color: #EA580C; +} + +.text-primary { + color: #F97316 !important; +} + +.form-control:focus { + border-color: #F97316; + box-shadow: 0 0 0 0.25rem rgba(249, 115, 22, 0.25); +} + +.nav-link.active { + color: #F97316 !important; + border-bottom: 2px solid #F97316; +} diff --git a/auth.php b/auth.php new file mode 100644 index 0000000..ad063ca --- /dev/null +++ b/auth.php @@ -0,0 +1,51 @@ +prepare("SELECT * FROM users WHERE email = ?"); + $stmt->execute([$email]); + $user = $stmt->fetch(); + + if ($user && password_verify($password, $user['password'])) { + session_regenerate_id(true); + $_SESSION['user_id'] = $user['id']; + $_SESSION['user_name'] = $user['name']; + $_SESSION['user_role'] = $user['role']; + header('Location: index.php'); + exit; + } else { + $_SESSION['login_error'] = 'Invalid email or password.'; + header('Location: login.php'); + exit; + } + } catch (PDOException $e) { + // In a real app, log this error. + $_SESSION['login_error'] = 'An error occurred. Please try again later.'; + header('Location: login.php'); + exit; + } +} diff --git a/create_order.php b/create_order.php new file mode 100644 index 0000000..fd70e27 --- /dev/null +++ b/create_order.php @@ -0,0 +1,119 @@ +beginTransaction(); + + // Generate order number (simple placeholder for now, will enhance later) + // For now, let's just use a timestamp based simple one, we will improve later. + $order_number = 'FMO' . date('YmdHis'); + + $stmt = $pdo->prepare('INSERT INTO orders (order_number, order_date, order_text, status, sales_rep_id) VALUES (?, ?, ?, ?, ?)'); + $stmt->execute([$order_number, $order_date, $order_text, 'Pending', $sales_rep_id]); + $pdo->commit(); + + $success_message = 'Order ' . $order_number . ' created successfully!'; + // Clear the form + $order_text = ''; + + // Send email notification to Dispatch + require_once __DIR__ . '/mail/MailService.php'; + $dispatch_email = 'info@focuzinternational.com'; // TODO: Make this configurable by Admin + $subject = 'New Order: ' . $order_number . ' (' . 'Pending' . ')'; + $html_body = '

A new order has been created:

' + . '

Order Number: ' . htmlspecialchars($order_number) . '

' + . '

Order Date: ' . htmlspecialchars($order_date) . '

' + . '

Order Text: ' . nl2br(htmlspecialchars($order_text)) . '

' + . '

Status: Pending

'; + $text_body = "A new order has been created:\n\n" + . "Order Number: {$order_number}\n" + . "Order Date: {$order_date}\n" + . "Order Text: {$order_text}\n" + . "Status: Pending"; + + $mail_result = MailService::sendMail($dispatch_email, $subject, $html_body, $text_body); + if (!empty($mail_result['error'])) { + // Log the email error, but don't fail the order creation + error_log('Email sending failed: ' . $mail_result['error']); + } + + } catch (PDOException $e) { + $pdo->rollBack(); + $errors[] = 'Database error: ' . $e->getMessage(); + } + } +} + +// Generate new CSRF token for the form +$_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + +?> + +
+

Create New Order

+ + + + + + + + + +
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + diff --git a/db/config.php b/db/config.php index 8d2bd66..2a200e4 100644 --- a/db/config.php +++ b/db/config.php @@ -4,14 +4,21 @@ define('DB_HOST', '127.0.0.1'); define('DB_NAME', 'app_36675'); define('DB_USER', 'app_36675'); define('DB_PASS', '131b38b5-41c0-4253-a34e-9c92b4bb9911'); +require_once __DIR__ . '/setup.php'; function db() { static $pdo; if (!$pdo) { - $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ]); + try { + $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ]); + // Run setup + setup_database($pdo); + } catch (PDOException $e) { + die("DB connection failed: " . $e->getMessage()); + } } return $pdo; } diff --git a/db/setup.php b/db/setup.php new file mode 100644 index 0000000..cdea52c --- /dev/null +++ b/db/setup.php @@ -0,0 +1,41 @@ +exec("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, + role ENUM('Admin', 'Sales Rep', 'Dispatch') NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + )"); + + $pdo->exec("CREATE TABLE IF NOT EXISTS orders ( + id INT AUTO_INCREMENT PRIMARY KEY, + order_number VARCHAR(255) NOT NULL UNIQUE, + order_date DATE NOT NULL, + order_text TEXT NOT NULL, + status ENUM('Pending', 'Query', 'Query Replied', 'Shipped', 'Cancelled') NOT NULL DEFAULT 'Pending', + sales_rep_id INT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (sales_rep_id) REFERENCES users(id) + )"); + + // Add a default admin user if one doesn't exist + $stmt = $pdo->query("SELECT COUNT(*) FROM users WHERE role = 'Admin'"); + if ($stmt->fetchColumn() == 0) { + $admin_email = 'admin@example.com'; + $admin_name = 'Admin'; + // In a real app, use a more secure password policy + $admin_password = password_hash('password', PASSWORD_DEFAULT); + $admin_role = 'Admin'; + + $insert_stmt = $pdo->prepare("INSERT INTO users (name, email, password, role) VALUES (?, ?, ?, ?)"); + $insert_stmt->execute([$admin_name, $admin_email, $admin_password, $admin_role]); + } + } catch (PDOException $e) { + // In a real app, you would log this error. + die("Database setup failed: " . $e->getMessage()); + } +} diff --git a/index.php b/index.php index 7205f3d..add4fe6 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,152 @@ prepare("SELECT COUNT(*) FROM orders " . $conditions . " AND status = 'Pending'"); + $stmt->execute($params); + $pending_orders_count = $stmt->fetchColumn(); + + // Pending Replies Count (Orders with status 'Query' or 'Query Replied') + $stmt = $pdo->prepare("SELECT COUNT(*) FROM orders " . $conditions . " AND (status = 'Query' OR status = 'Query Replied')"); + $stmt->execute($params); + $pending_replies_count = $stmt->fetchColumn(); + + // Shipped Orders This Month Count + $current_month_start = date('Y-m-01 00:00:00'); + $current_month_end = date('Y-m-t 23:59:59'); + + $shipped_sql = "SELECT COUNT(*) FROM orders " . $conditions . " AND status = 'Shipped' AND created_at >= :start_date AND created_at <= :end_date"; + $shipped_params = $params; + $shipped_params[':start_date'] = $current_month_start; + $shipped_params[':end_date'] = $current_month_end; + + $stmt = $pdo->prepare($shipped_sql); + $stmt->execute($shipped_params); + $shipped_orders_month_count = $stmt->fetchColumn(); + + // --- Fetch Order List --- + $orders = []; + $sql = "SELECT o.id, o.order_number, o.order_date, o.order_text, o.status, u.name as sales_rep_name + FROM orders o + JOIN users u ON o.sales_rep_id = u.id"; + + if ($user_role === 'Sales Rep') { + $sql .= " WHERE o.sales_rep_id = :user_id"; + $stmt = $pdo->prepare($sql); + $stmt->bindParam(':user_id', $user_id, PDO::PARAM_INT); + } else { + // Dispatch and Admin can see all orders + $stmt = $pdo->prepare($sql); + } + $stmt->execute(); + $orders = $stmt->fetchAll(PDO::FETCH_ASSOC); +} catch (PDOException $e) { + error_log("Database error fetching dashboard data or orders: " . $e->getMessage()); + echo ''; +} -$phpVersion = PHP_VERSION; -$now = date('Y-m-d H:i:s'); ?> - - - - - - New Style - - - - - - - - - - - - - - - - - - - - - -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+
+
+
+
Pending Orders
+

+
+
-
- - - +
+
+
+
Pending Replies
+

+
+
+
+
+
+
+
Shipped This Month
+

+
+
+
+ + +
+
+
+
+

Welcome, !

+

Your current role:

+
+
+
+ +
+
+
+
Order List
+ +

No orders found.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Order NumberDateSales RepTextStatusActions
... + View + + Edit + +
+
+ +
+
+
+
+ + diff --git a/login.php b/login.php new file mode 100644 index 0000000..5b2c7f7 --- /dev/null +++ b/login.php @@ -0,0 +1,63 @@ + + + + + + Login - Focuz Order Management + + + + + + + + + +
+
+
+
+
+
+ +

Focuz Order Management

+

Please sign in to continue

+
+ + + + + +
+
+ + +
+
+ + +
+
+ +
+
+
+ Default credentials: admin@example.com / password +
+
+
+
+
+
+ + + + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..95db42c --- /dev/null +++ b/logout.php @@ -0,0 +1,6 @@ + + + + + + + diff --git a/partials/header.php b/partials/header.php new file mode 100644 index 0000000..b582eaa --- /dev/null +++ b/partials/header.php @@ -0,0 +1,56 @@ + + + + + + + <?php echo isset($page_title) ? htmlspecialchars($page_title) : 'Dashboard'; ?> - Focuz Order Management + + + + + + + + + + + +