Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions assets/css/customer.css
Original file line number Diff line number Diff line change
@@ -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;
}
76 changes: 34 additions & 42 deletions auth/login.php
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
<?php
include '../src/config/config.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
$username = $_POST['username'];
$password = $_POST['password'];
// Start session if not started
if (session_status() === PHP_SESSION_NONE) {
session_start();
}

// If already logged in, redirect to index.php
if (isset($_SESSION['users']) && !empty($_SESSION['users'])) {
header("Location: ../index.php");
exit();
}

$error = ""; // initialize error variable

// Prepared statement
if ($_SERVER['REQUEST_METHOD'] === 'POST') {

$username = trim($_POST['username']);
$password = trim($_POST['password']);

// Prepared statement to fetch user
$stmt = $conn->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!";
}
Expand All @@ -33,42 +47,20 @@
<html>

<head>
<title>Admin Login</title>
<title>Login</title>
<link rel="stylesheet" href="../assets/css/login.css">
<script src="https://kit.fontawesome.com/f02a36f28e.js" crossorigin="anonymous"></script>
</head>

<body class="login-body">

<body>
<div class="login-card">
<!-- <img src="../assets/img/nadine_logo.jpg" alt="logo"> -->
<h2 style="margin-bottom: 20px;">Admin Login</h2>

<h2>Login</h2>
<form method="POST">
<input type="text" name="username" placeholder="Username" required>

<div style="position: relative;">
<input type="password" id="password" name="password" placeholder="Password" required>
<span id="togglePassword"
style="position:absolute; right:10px; top:35%; transform:translateY(-50%); cursor:pointer;">

</span>
</div>

<?php if (isset($error)) echo "<p style='color:red; margin-bottom:10px;'>$error</p>"; ?>

<input type="password" name="password" placeholder="Password" required>
<?php if (!empty($error)) echo "<p style='color:red;'>$error</p>"; ?>
<button type="submit">Login</button>
</form>
</div>

<script>
const toggle = document.getElementById("togglePassword");
const password = document.getElementById("password");
toggle.addEventListener("click", function() {
const type = password.getAttribute("type") === "password" ? "text" : "password";
password.setAttribute("type", type);
});
</script>
</body>

</html>
28 changes: 14 additions & 14 deletions src/accounts/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
}
6 changes: 3 additions & 3 deletions src/include/sidebar.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@
<a href="<?= $base_url ?>src/accounts/staff.php" class="<?= $currentPage == 'staff.php' ? 'active' : '' ?>">
<i class="fas fa-user-shield"></i> Accounts
</a>
<!--
<a href="#" class="<?= $currentPage == 'customer.php' ? 'active' : '' ?>">

<a href="<?= $base_url ?>src/users/customers.php" class="<?= $currentPage == 'customers.php' ? 'active' : '' ?>">
<i class="fas fa-users"></i> Customer
</a>
-->

<a href="<?= $base_url ?>src/dashboard/stats.php" class="<?= $currentPage == 'stats.php' ? 'active' : '' ?>">
<i class="fas fa-chart-bar"></i> Statistics
</a>
Expand Down
Loading