diff --git a/assets/css/customer.css b/assets/css/customer.css new file mode 100644 index 0000000..92e73e2 --- /dev/null +++ b/assets/css/customer.css @@ -0,0 +1,139 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'cremona', serif; + background: #cbd5c0; + display: flex; + min-height: 100vh; +} + +/* ===== MAIN CONTENT ===== */ +.content { + margin-left: 220px; + padding: 30px 25px; + flex: 1; + max-width: 100%; +} + +/* ===== HEADER ===== */ +.content h1 { + font-size: 28px; + margin-bottom: 8px; + color: #111827; +} + +.content p { + margin-bottom: 25px; + color: #4b5563; + font-size: 14px; +} + +/* ===== Orders Table Wrapper ===== */ +.orders-container { + background: #fff; + padding: 20px; + border-radius: 16px; + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.05); + overflow-x: auto; +} + +/* ===== Orders Table ===== */ +.orders-table { + width: 100%; + border-collapse: collapse; + min-width: 700px; +} + +.orders-table th, +.orders-table td { + padding: 12px 15px; + text-align: left; + font-size: 14px; +} + +.orders-table th { + background: #ccf7af9f; + color: #fff; + color: #121213; + font-weight: 600; + position: sticky; + top: 0; +} + +.orders-table tr:nth-child(even) { + background: #f9fafb; +} + +.orders-table tr:hover { + background: #e0e7ff; + cursor: pointer; +} + +/* Responsive table for mobile */ +@media(max-width:768px) { + + .orders-table, + .orders-table thead, + .orders-table tbody, + .orders-table th, + .orders-table td, + .orders-table tr { + display: block; + } + + .orders-table thead tr { + display: none; + } + + .orders-table td { + position: relative; + padding-left: 50%; + border-bottom: 1px solid #ddd; + } + + .orders-table td:before { + content: attr(data-label); + position: absolute; + left: 15px; + top: 12px; + font-weight: 600; + color: #2563eb; + } +} + +/* ===== Pagination ===== */ +.pagination { + display: flex; + justify-content: center; + align-items: center; + margin-top: 20px; + gap: 10px; +} + +.page-btn { + padding: 8px 16px; + border-radius: 8px; + background: #2e7d32; + color: #fff; + text-decoration: none; + font-weight: 500; + transition: 0.2s; +} + +.page-btn:hover { + background: #2e7d32a8; +} + +.page-btn.disabled { + background: #2e7d323d; + cursor: not-allowed; +} + +.page-info { + font-weight: 500; + color: #374151; +} \ No newline at end of file diff --git a/auth/login.php b/auth/login.php index 60fefca..de9f944 100644 --- a/auth/login.php +++ b/auth/login.php @@ -1,29 +1,43 @@ prepare("SELECT * FROM users WHERE username = ?"); $stmt->bind_param("s", $username); $stmt->execute(); $result = $stmt->get_result(); - if ($result->num_rows > 0) { - $user = $result->fetch_assoc(); + $user = $result->fetch_assoc(); + + // Combine entered password with stored salt + $passwordWithSalt = $password . ($user['salt'] ?? ''); - // Verify hashed password - if (password_verify($password, $user['password'])) { - $_SESSION['users'] = $user['username']; - $_SESSION['role'] = $user['role']; + if ($user && password_verify($passwordWithSalt, $user['password'])) { + // Successful login + session_regenerate_id(true); // prevent session fixation + $_SESSION['users'] = $user['username']; + $_SESSION['role'] = $user['role']; - header("Location: ../index.php"); - exit(); - } else { - $error = "Invalid credentials!"; - } + header("Location: ../index.php"); + exit(); } else { $error = "Invalid credentials!"; } @@ -33,42 +47,20 @@ - Admin Login + Login - - - +
- -

Admin Login

- +

Login

- -
- - - - -
- - $error

"; ?> - + + $error

"; ?>
- - \ No newline at end of file diff --git a/src/accounts/register.php b/src/accounts/register.php index 36c8f11..110ffea 100644 --- a/src/accounts/register.php +++ b/src/accounts/register.php @@ -2,19 +2,21 @@ include '../config/config.php'; checkLogin(); -// Only allow POST request -if ($_SERVER["REQUEST_METHOD"] == "POST") { +if ($_SERVER["REQUEST_METHOD"] === "POST") { - // Get form data - $username = $_POST['username']; - $password = $_POST['password']; - $fullname = $_POST['fullname']; - $role = $_POST['role']; + $username = trim($_POST['username']); + $password = trim($_POST['password']); + $fullname = trim($_POST['fullname']); + $role = trim($_POST['role']); - // 🔐 Hash password (IMPORTANT) - $hashedPassword = password_hash($password, PASSWORD_DEFAULT); + // 🔐 Generate per-user salt + $salt = bin2hex(random_bytes(16)); // 16 bytes = 32-character hex - // Check if username already exists + // 🔐 Combine password + salt, then hash + $passwordWithSalt = $password . $salt; + $hashedPassword = password_hash($passwordWithSalt, PASSWORD_DEFAULT); + + // Check if username exists $check = $conn->prepare("SELECT id FROM users WHERE username = ?"); $check->bind_param("s", $username); $check->execute(); @@ -26,18 +28,16 @@ } // Insert user - $stmt = $conn->prepare("INSERT INTO users (username, password, fullname, role) VALUES (?, ?, ?, ?)"); - $stmt->bind_param("ssss", $username, $hashedPassword, $fullname, $role); + $stmt = $conn->prepare("INSERT INTO users (username, password, salt, fullname, role) VALUES (?, ?, ?, ?, ?)"); + $stmt->bind_param("sssss", $username, $hashedPassword, $salt, $fullname, $role); if ($stmt->execute()) { - // Success → redirect back header("Location: staff.php"); exit(); } else { echo "Error: " . $conn->error; } } else { - // If accessed directly header("Location: staff.php"); exit(); } diff --git a/src/include/sidebar.php b/src/include/sidebar.php index 2daefdc..f06ae0c 100644 --- a/src/include/sidebar.php +++ b/src/include/sidebar.php @@ -47,11 +47,11 @@ Accounts - + Statistics diff --git a/src/users/customers.php b/src/users/customers.php index a4d40d4..5464a32 100644 --- a/src/users/customers.php +++ b/src/users/customers.php @@ -1,41 +1,82 @@ - +connect_error) die("Connection failed: " . $conn->connect_error); + + +$limit = 10; // orders per page +$page = isset($_GET['page']) ? (int)$_GET['page'] : 1; +$page = max($page, 1); +$offset = ($page - 1) * $limit; + +$totalRows = $conn->query("SELECT COUNT(*) AS total FROM orders")->fetch_assoc()['total']; +$totalPages = ceil($totalRows / $limit); + +$orders = $conn->query(" + SELECT orderID, customer_name, address, phone + FROM orders + ORDER BY order_date DESC + LIMIT $limit OFFSET $offset +"); +?> Customers - - + + + - + +

Customer List

-

View all customers who have placed orders.

+

View all customers who have placed orders.

- - - - - - - - query("SELECT * FROM customers"); - while ($row = $result->fetch_assoc()) { - echo " - - - - "; - } - ?> +
NameEmailPhone
{$row['name']}{$row['email']}{$row['phone']}
+ + + + + + + + + fetch_assoc()): ?> + + + + + + +
NameAddressPhone
+ + +
+ \ No newline at end of file