Employment attendance system
This commit is contained in:
parent
3b25d53f36
commit
894b41720e
157
add_employee.php
Normal file
157
add_employee.php
Normal file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
// Check if user is logged in and is an Admin
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true || $_SESSION['role'] !== 'Admin') {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$username = $password = $role = '';
|
||||
$username_err = $password_err = $role_err = '';
|
||||
$success_msg = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Validate username
|
||||
if (empty(trim($_POST['username']))) {
|
||||
$username_err = 'Please enter a username.';
|
||||
} else {
|
||||
// Check if username already exists
|
||||
$sql = 'SELECT id FROM users WHERE username = :username';
|
||||
if ($stmt = db()->prepare($sql)) {
|
||||
$stmt->bindParam(':username', trim($_POST['username']), PDO::PARAM_STR);
|
||||
if ($stmt->execute()) {
|
||||
if ($stmt->rowCount() == 1) {
|
||||
$username_err = 'This username is already taken.';
|
||||
} else {
|
||||
$username = trim($_POST['username']);
|
||||
}
|
||||
} else {
|
||||
echo 'Oops! Something went wrong. Please try again later.';
|
||||
}
|
||||
unset($stmt);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate password
|
||||
if (empty(trim($_POST['password']))) {
|
||||
$password_err = 'Please enter a password.';
|
||||
} elseif (strlen(trim($_POST['password'])) < 6) {
|
||||
$password_err = 'Password must have at least 6 characters.';
|
||||
} else {
|
||||
$password = trim($_POST['password']);
|
||||
}
|
||||
|
||||
// Validate role
|
||||
if (empty($_POST['role'])) {
|
||||
$role_err = 'Please select a role.';
|
||||
} else {
|
||||
$role = $_POST['role'];
|
||||
}
|
||||
|
||||
// Check input errors before inserting in database
|
||||
if (empty($username_err) && empty($password_err) && empty($role_err)) {
|
||||
$sql = 'INSERT INTO users (username, password, role) VALUES (:username, :password, :role)';
|
||||
|
||||
if ($stmt = db()->prepare($sql)) {
|
||||
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':password', $hashed_password, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':role', $role, PDO::PARAM_STR);
|
||||
|
||||
// Hash password
|
||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$success_msg = 'Employee added successfully!';
|
||||
// Clear form fields
|
||||
$username = $password = $role = '';
|
||||
} else {
|
||||
echo 'Oops! Something went wrong. Please try again later.';
|
||||
}
|
||||
unset($stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Add Employee - Employee Attendance System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.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=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="sidebar">
|
||||
<h4 class="mb-4 fw-bold">Attendance System</h4>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php"><i class="bi bi-grid-fill me-2"></i> Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#"><i class="bi bi-person-plus-fill me-2"></i> Add Employee</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#"><i class="bi bi-people-fill me-2"></i> Employees</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#"><i class="bi bi-calendar-check-fill me-2"></i> Attendance</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#"><i class="bi bi-file-earmark-bar-graph-fill me-2"></i> Reports</a>
|
||||
</li>
|
||||
<li class="nav-item mt-auto">
|
||||
<a class="nav-link" href="logout.php"><i class="bi bi-box-arrow-left me-2"></i> Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="container-fluid">
|
||||
<h1 class="mt-4">Add New Employee</h1>
|
||||
<p class="lead">Fill out the form to add a new employee to the system.</p>
|
||||
|
||||
<?php if(!empty($success_msg)): ?>
|
||||
<div class="alert alert-success"><?php echo $success_msg; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post" class="mt-4 card p-4 bg-white border-0 shadow-sm">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" name="username" id="username" class="form-control <?php echo (!empty($username_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $username; ?>">
|
||||
<span class="invalid-feedback"><?php echo $username_err; ?></span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<input type="password" name="password" id="password" class="form-control <?php echo (!empty($password_err)) ? 'is-invalid' : ''; ?>">
|
||||
<span class="invalid-feedback"><?php echo $password_err; ?></span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="role" class="form-label">Role</label>
|
||||
<select name="role" id="role" class="form-select <?php echo (!empty($role_err)) ? 'is-invalid' : ''; ?>">
|
||||
<option value="">Select a role...</option>
|
||||
<option value="Admin" <?php if($role == 'Admin') echo 'selected'; ?>>Admin</option>
|
||||
<option value="HR" <?php if($role == 'HR') echo 'selected'; ?>>HR</option>
|
||||
<option value="Employee" <?php if($role == 'Employee') echo 'selected'; ?>>Employee</option>
|
||||
<option value="Supervisor" <?php if($role == 'Supervisor') echo 'selected'; ?>>Supervisor</option>
|
||||
</select>
|
||||
<span class="invalid-feedback"><?php echo $role_err; ?></span>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary" style="background-color: #3B82F6;">Add Employee</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
43
assets/css/custom.css
Normal file
43
assets/css/custom.css
Normal file
@ -0,0 +1,43 @@
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
background-color: #F3F4F6;
|
||||
}
|
||||
|
||||
.login-body {
|
||||
background-image: linear-gradient(to right, #3B82F6, #1E40AF);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
box-shadow: 0 0 0 0.25rem rgba(59, 130, 246, 0.25);
|
||||
border-color: #3B82F6;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 250px;
|
||||
padding: 20px;
|
||||
background-color: #1F2937;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
color: #D1D5DB;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover, .sidebar .nav-link.active {
|
||||
color: #fff;
|
||||
background-color: #374151;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-left: 250px;
|
||||
padding: 20px;
|
||||
}
|
||||
111
attendance_report.php
Normal file
111
attendance_report.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['user_id']) || !in_array($_SESSION['role'], ['Admin', 'HR'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
require_once 'db/config.php';
|
||||
include 'sidebar.php';
|
||||
|
||||
// Fetch attendance data
|
||||
$search_date = isset($_GET['search_date']) ? $_GET['search_date'] : '';
|
||||
$search_name = isset($_GET['search_name']) ? $_GET['search_name'] : '';
|
||||
|
||||
$sql = "
|
||||
SELECT a.id, e.name, a.status, a.date, a.check_in_time, a.check_out_time
|
||||
FROM attendance a
|
||||
JOIN employees e ON a.employee_id = e.id
|
||||
";
|
||||
|
||||
$where_clauses = [];
|
||||
$params = [];
|
||||
|
||||
if (!empty($search_date)) {
|
||||
$where_clauses[] = "a.date = :date";
|
||||
$params['date'] = $search_date;
|
||||
}
|
||||
|
||||
if (!empty($search_name)) {
|
||||
$where_clauses[] = "e.name LIKE :name";
|
||||
$params['name'] = '%' . $search_name . '%';
|
||||
}
|
||||
|
||||
if (!empty($where_clauses)) {
|
||||
$sql .= " WHERE " . implode(' AND ', $where_clauses);
|
||||
}
|
||||
|
||||
$stmt = db()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$attendance_records = $stmt->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="d-sm-flex align-items-center justify-content-between mb-4">
|
||||
<h1 class="h3 mb-0 text-gray-800">This is the Attendance Report Page</h1>
|
||||
</div>
|
||||
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header py-3">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Filter by Date</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="get" action="attendance_report.php">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="search_date">Select Date</label>
|
||||
<input type="date" class="form-control" id="search_date" name="search_date" value="<?= htmlspecialchars($search_date) ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="search_name">Employee Name</label>
|
||||
<input type="text" class="form-control" id="search_name" name="search_name" placeholder="Enter employee name..." value="<?= isset($_GET['search_name']) ? htmlspecialchars($_GET['search_name']) : '' ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header py-3">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Attendance Records</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Employee Name</th>
|
||||
<th>Status</th>
|
||||
<th>Date</th>
|
||||
<th>Check-in Time</th>
|
||||
<th>Check-out Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($attendance_records)): ?>
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">No records found for this date.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($attendance_records as $record): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($record['name']) ?></td>
|
||||
<td><?= htmlspecialchars($record['status']) ?></td>
|
||||
<td><?= htmlspecialchars($record['date']) ?></td>
|
||||
<td><?= htmlspecialchars($record['check_in_time']) ?></td>
|
||||
<td><?= htmlspecialchars($record['check_out_time']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
40
auth.php
Normal file
40
auth.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
|
||||
$username = $_POST['username'];
|
||||
$password = $_POST['password'];
|
||||
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
|
||||
$stmt->execute([$username]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
if ($user) {
|
||||
if (password_verify($password, $user['password'])) {
|
||||
$_SESSION['loggedin'] = true;
|
||||
$_SESSION['id'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['role'] = $user['role'];
|
||||
header("location: index.php");
|
||||
exit;
|
||||
} else {
|
||||
$_SESSION['error'] = "Invalid username or password.";
|
||||
header("location: login.php");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$_SESSION['error'] = "Invalid username or password.";
|
||||
header("location: login.php");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
?>
|
||||
@ -15,3 +15,23 @@ function db() {
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
function init_db() {
|
||||
$pdo = db();
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
role ENUM('Admin', 'HR', 'Employee', 'Supervisor') NOT NULL
|
||||
);");
|
||||
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
|
||||
$stmt->execute(['admin']);
|
||||
if ($stmt->rowCount() == 0) {
|
||||
$password = password_hash('password', PASSWORD_DEFAULT);
|
||||
$stmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
|
||||
$stmt->execute(['admin', $password, 'Admin']);
|
||||
}
|
||||
}
|
||||
|
||||
init_db();
|
||||
|
||||
21
db/migrate_leave_requests.php
Normal file
21
db/migrate_leave_requests.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
require_once 'config.php';
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
$sql = "CREATE TABLE IF NOT EXISTS leave_requests (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
employee_id INT NOT NULL,
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE NOT NULL,
|
||||
reason TEXT,
|
||||
status ENUM('pending', 'approved', 'rejected') DEFAULT 'pending',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (employee_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);";
|
||||
$pdo->exec($sql);
|
||||
echo "Table 'leave_requests' created successfully." . PHP_EOL;
|
||||
} catch (PDOException $e) {
|
||||
die("Error creating table: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
22
delete_employee.php
Normal file
22
delete_employee.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true || $_SESSION['role'] !== 'Admin') {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = $_GET['id'] ?? null;
|
||||
if (!$id) {
|
||||
header('location: view_employees.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
|
||||
header('location: view_employees.php');
|
||||
exit;
|
||||
?>
|
||||
79
edit_employee.php
Normal file
79
edit_employee.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true || $_SESSION['role'] !== 'Admin') {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = $_GET['id'] ?? null;
|
||||
if (!$id) {
|
||||
header('location: view_employees.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$user) {
|
||||
die('User not found.');
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$username = $_POST['username'];
|
||||
$role = $_POST['role'];
|
||||
|
||||
$updateStmt = $pdo->prepare("UPDATE users SET username = ?, role = ? WHERE id = ?");
|
||||
$updateStmt->execute([$username, $role, $id]);
|
||||
|
||||
header('location: view_employees.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 Employee - Employee Attendance System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php include 'sidebar.php'; ?>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="container-fluid">
|
||||
<h1 class="mt-4">Edit Employee</h1>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<form action="edit_employee.php?id=<?php echo $id; ?>" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="username" name="username" value="<?php echo htmlspecialchars($user['username']); ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="role" class="form-label">Role</label>
|
||||
<select class="form-select" id="role" name="role">
|
||||
<option value="Employee" <?php echo ($user['role'] == 'Employee') ? 'selected' : ''; ?>>Employee</option>
|
||||
<option value="Admin" <?php echo ($user['role'] == 'Admin') ? 'selected' : ''; ?>>Admin</option>
|
||||
<option value="HR" <?php echo ($user['role'] == 'HR') ? 'selected' : ''; ?>>HR</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Update Employee</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
46
get_leave_events.php
Normal file
46
get_leave_events.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once 'db/config.php';
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
echo json_encode([]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SESSION['role'] !== 'Admin' && $_SESSION['role'] !== 'HR' && $_SESSION['role'] !== 'Employee') {
|
||||
echo json_encode([]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$events = [];
|
||||
try {
|
||||
$pdo = db();
|
||||
$sql = "SELECT lr.start_date as start, lr.end_date as end, u.username as title FROM leave_requests lr JOIN users u ON lr.employee_id = u.id WHERE lr.status = 'approved'";
|
||||
|
||||
if ($_SESSION['role'] == 'Employee') {
|
||||
$sql .= " AND lr.employee_id = :employee_id";
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
if ($_SESSION['role'] == 'Employee') {
|
||||
$stmt->bindParam(':employee_id', $_SESSION['id'], PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
$events = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Adjust end date for FullCalendar
|
||||
foreach ($events as &$event) {
|
||||
$event['end'] = date('Y-m-d', strtotime($event['end'] . ' +1 day'));
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// On error, return empty array
|
||||
echo json_encode([]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode($events);
|
||||
?>
|
||||
287
index.php
287
index.php
@ -1,150 +1,159 @@
|
||||
<?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');
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once 'db/config.php';
|
||||
$pdo = db();
|
||||
$today = date('Y-m-d');
|
||||
|
||||
// Fetch total employees
|
||||
$stmt_total = $pdo->query('SELECT COUNT(*) FROM users');
|
||||
$total_employees = $stmt_total->fetchColumn();
|
||||
|
||||
// Fetch attendance stats for today
|
||||
$stmt_attendance = $pdo->prepare("SELECT status, COUNT(*) as count FROM attendance WHERE attendance_date = ? GROUP BY status");
|
||||
$stmt_attendance->execute([$today]);
|
||||
$attendance_stats = $stmt_attendance->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
|
||||
$on_time_today = $attendance_stats['Present'] ?? 0;
|
||||
$late_today = $attendance_stats['Late'] ?? 0;
|
||||
$absent_today = $attendance_stats['Absent'] ?? 0;
|
||||
|
||||
// Fetch pending leave requests for Admin/HR
|
||||
$pending_leave_requests = 0;
|
||||
if (in_array($_SESSION['role'], ['Admin', 'HR'])) {
|
||||
$stmt_leave = $pdo->query("SELECT COUNT(*) FROM leave_requests WHERE status = 'pending'");
|
||||
$pending_leave_requests = $stmt_leave->fetchColumn();
|
||||
}
|
||||
|
||||
?>
|
||||
<!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; ?>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard - Employee Attendance System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.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=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>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" 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 class="d-flex">
|
||||
<?php include 'sidebar.php'; ?>
|
||||
|
||||
<div class="main-content flex-grow-1 p-4">
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h3 mb-0 text-gray-800">Dashboard</h1>
|
||||
<p class="lead mb-0">Welcome, <strong><?php echo htmlspecialchars($_SESSION['username']); ?>!</strong></p>
|
||||
</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>
|
||||
|
||||
<div class="row">
|
||||
<!-- Total Employees Card -->
|
||||
<div class="col-xl-3 col-md-6 mb-4">
|
||||
<div class="card border-left-primary shadow h-100 py-2">
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Total Employees</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $total_employees; ?></div>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||
</footer>
|
||||
<div class="col-auto">
|
||||
<i class="bi bi-people-fill h2 text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- On Time Today Card -->
|
||||
<div class="col-xl-3 col-md-6 mb-4">
|
||||
<div class="card border-left-success shadow h-100 py-2">
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">On Time Today</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $on_time_today; ?></div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="bi bi-check-circle-fill h2 text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Late Today Card -->
|
||||
<div class="col-xl-3 col-md-6 mb-4">
|
||||
<div class="card border-left-warning shadow h-100 py-2">
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Late Today</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $late_today; ?></div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="bi bi-exclamation-triangle-fill h2 text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Absent Today Card -->
|
||||
<div class="col-xl-3 col-md-6 mb-4">
|
||||
<div class="card border-left-danger shadow h-100 py-2">
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-danger text-uppercase mb-1">Absent Today</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $absent_today; ?></div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="bi bi-x-circle-fill h2 text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (in_array($_SESSION['role'], ['Admin', 'HR'])): ?>
|
||||
<div class="row">
|
||||
<div class="col-xl-3 col-md-6 mb-4">
|
||||
<div class="card border-left-info shadow h-100 py-2">
|
||||
<a href="leave_requests.php" class="text-decoration-none">
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col mr-2">
|
||||
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">Pending Leave Requests</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $pending_leave_requests; ?></div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="bi bi-calendar-plus-fill h2 text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<p>From here you can manage employees, track attendance, and generate reports.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
230
leave_requests.php
Normal file
230
leave_requests.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SESSION['role'] !== 'Admin' && $_SESSION['role'] !== 'HR' && $_SESSION['role'] !== 'Employee') {
|
||||
header('location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$requests = [];
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
$sql = "SELECT lr.*, u.username FROM leave_requests lr JOIN users u ON lr.employee_id = u.id";
|
||||
|
||||
if ($_SESSION['role'] == 'Employee') {
|
||||
$sql .= " WHERE lr.employee_id = :employee_id";
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY lr.created_at DESC";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
if ($_SESSION['role'] == 'Employee') {
|
||||
$stmt->bindParam(':employee_id', $_SESSION['id'], PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
$requests = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
die("Could not fetch leave requests.");
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Leave Requests - Employee Attendance System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.css">
|
||||
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.css' rel='stylesheet' />
|
||||
</head>
|
||||
<body>
|
||||
<?php include 'sidebar.php'; ?>
|
||||
<div class="main-content">
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h1 class="mt-4">Leave Requests</h1>
|
||||
<div>
|
||||
<a href="submit_leave_request.php" class="btn btn-primary">Submit New Request</a>
|
||||
<button id="toggle-view" class="btn btn-secondary">Calendar View</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="lead">Manage and view employee leave requests.</p>
|
||||
<?php if ($_SESSION['role'] === 'Admin' || $_SESSION['role'] === 'HR'): ?>
|
||||
<p class="text-muted">You are viewing all employee leave requests.</p>
|
||||
<?php else: ?>
|
||||
<p class="text-muted">You are viewing your own leave requests.</p>
|
||||
<?php endif; ?> <div id="calendar-view" style="display: none;">
|
||||
<div id="calendar"></div>
|
||||
</div>
|
||||
|
||||
<div id="list-view">
|
||||
|
||||
<div class="card shadow-sm">
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<table class="table table-hover">
|
||||
|
||||
<thead class="table-light">
|
||||
|
||||
<tr>
|
||||
|
||||
<th scope="col">Employee</th>
|
||||
|
||||
<th scope="col">Start Date</th>
|
||||
|
||||
<th scope="col">End Date</th>
|
||||
|
||||
<th scope="col">Reason</th>
|
||||
|
||||
<th scope="col">Status</th>
|
||||
|
||||
<th scope="col">Actions</th>
|
||||
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<?php if (empty($requests)):
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
|
||||
<td colspan="6" class="text-center">No leave requests found.</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<?php else:
|
||||
|
||||
?>
|
||||
|
||||
<?php foreach ($requests as $request):
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><?php echo htmlspecialchars($request['username']); ?></td>
|
||||
|
||||
<td><?php echo htmlspecialchars($request['start_date']); ?></td>
|
||||
|
||||
<td><?php echo htmlspecialchars($request['end_date']); ?></td>
|
||||
|
||||
<td><?php echo htmlspecialchars($request['reason']); ?></td>
|
||||
|
||||
<td>
|
||||
|
||||
<span class="badge bg-<?php echo $request['status'] == 'approved' ? 'success' : ($request['status'] == 'rejected' ? 'danger' : 'warning'); ?>">
|
||||
|
||||
<?php echo ucfirst($request['status']); ?>
|
||||
|
||||
</span>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
<?php if (($_SESSION['role'] === 'Admin' || $_SESSION['role'] === 'HR') && $request['status'] === 'pending'): ?>
|
||||
|
||||
<a href="update_leave_status.php?id=<?php echo $request['id']; ?>&status=approved" class="btn btn-sm btn-outline-success">Approve</a>
|
||||
|
||||
<a href="update_leave_status.php?id=<?php echo $request['id']; ?>&status=rejected" class="btn btn-sm btn-outline-danger">Reject</a>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js'></script>
|
||||
|
||||
<script>
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
|
||||
var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
|
||||
initialView: 'dayGridMonth',
|
||||
|
||||
events: 'get_leave_events.php',
|
||||
|
||||
height: 'auto'
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
var listView = document.getElementById('list-view');
|
||||
|
||||
var calendarView = document.getElementById('calendar-view');
|
||||
|
||||
var toggleButton = document.getElementById('toggle-view');
|
||||
|
||||
|
||||
|
||||
toggleButton.addEventListener('click', function() {
|
||||
|
||||
if (listView.style.display === 'none') {
|
||||
|
||||
listView.style.display = 'block';
|
||||
|
||||
calendarView.style.display = 'none';
|
||||
|
||||
toggleButton.textContent = 'Calendar View';
|
||||
|
||||
} else {
|
||||
|
||||
listView.style.display = 'none';
|
||||
|
||||
calendarView.style.display = 'block';
|
||||
|
||||
toggleButton.textContent = 'List View';
|
||||
|
||||
calendar.render();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
60
login.php
Normal file
60
login.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
|
||||
header('location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$error = '';
|
||||
if (isset($_SESSION['error']) && !empty($_SESSION['error'])) {
|
||||
$error = $_SESSION['error'];
|
||||
unset($_SESSION['error']);
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login - Employee Attendance System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.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=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body class="login-body">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card shadow-lg border-0 rounded-lg mt-5">
|
||||
<div class="card-header bg-primary text-white text-center">
|
||||
<h3 class="fw-bold my-4">Employee Attendance System</h3>
|
||||
</div>
|
||||
<div class="card-body p-4 p-sm-5">
|
||||
<form action="auth.php" method="post">
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
|
||||
<?php endif; ?>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="username" name="username" placeholder="Username" required>
|
||||
<label for="username">Username</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="password" class="form-control" id="password" name="password" placeholder="Password" required>
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-primary btn-lg fw-bold" type="submit">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
7
logout.php
Normal file
7
logout.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
session_start();
|
||||
$_SESSION = array();
|
||||
session_destroy();
|
||||
header("location: login.php");
|
||||
exit;
|
||||
?>
|
||||
102
mark_attendance.php
Normal file
102
mark_attendance.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
require_once 'auth.php';
|
||||
require_once 'db/config.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
$employee_id = $_POST['employee_id'];
|
||||
$action = $_POST['action'];
|
||||
$current_time = date('H:i:s');
|
||||
$current_date = date('Y-m-d');
|
||||
|
||||
if ($action === 'check-in') {
|
||||
$stmt = db()->prepare("SELECT id FROM attendance WHERE employee_id = ? AND date = ?");
|
||||
$stmt->execute([$employee_id, $current_date]);
|
||||
$attendance_record = $stmt->fetch();
|
||||
|
||||
if ($attendance_record) {
|
||||
$stmt = db()->prepare("UPDATE attendance SET check_in_time = ?, status = 'Present' WHERE id = ?");
|
||||
$stmt->execute([$current_time, $attendance_record['id']]);
|
||||
} else {
|
||||
$stmt = db()->prepare("INSERT INTO attendance (employee_id, date, status, check_in_time) VALUES (?, ?, 'Present', ?)");
|
||||
$stmt->execute([$employee_id, $current_date, $current_time]);
|
||||
}
|
||||
} elseif ($action === 'check-out') {
|
||||
$stmt = db()->prepare("UPDATE attendance SET check_out_time = ? WHERE employee_id = ? AND date = ?");
|
||||
$stmt->execute([$current_time, $employee_id, $current_date]);
|
||||
}
|
||||
|
||||
header('Location: mark_attendance.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
// Only allow Admin and HR to access this page
|
||||
if (!isset($_SESSION['user_role']) || ($_SESSION['user_role'] !== 'Admin' && $_SESSION['user_role'] !== 'HR')) {
|
||||
header('Location: index.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
$today = date('Y-m-d');
|
||||
|
||||
// Fetch all employees (users)
|
||||
$stmt = $pdo->prepare('SELECT id, username, role FROM users ORDER BY username');
|
||||
$stmt->execute();
|
||||
$employees = $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>Mark Attendance</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="d-flex">
|
||||
<?php include 'sidebar.php'; ?>
|
||||
<div class="container-fluid main-content">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h1 class="h5 mb-0">Mark Daily Attendance</h1>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Employee Name</th>
|
||||
<th>Role</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($employees as $employee): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($employee['username']); ?></td>
|
||||
<td><?php echo htmlspecialchars($employee['role']); ?></td>
|
||||
<td class="text-center">
|
||||
<form action="mark_attendance.php" method="post" style="display: inline-block;">
|
||||
<input type="hidden" name="employee_id" value="<?= $employee['id'] ?>">
|
||||
<button type="submit" name="action" value="check-in" class="btn btn-success btn-sm">Check-in</button>
|
||||
</form>
|
||||
<form action="mark_attendance.php" method="post" style="display: inline-block;">
|
||||
<input type="hidden" name="employee_id" value="<?= $employee['id'] ?>">
|
||||
<button type="submit" name="action" value="check-out" class="btn btn-danger btn-sm">Check-out</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
70
profile.php
Normal file
70
profile.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION["role"])) {
|
||||
header("location: login.php");
|
||||
}
|
||||
require 'db/config.php';
|
||||
|
||||
$username = $_SESSION["username"];
|
||||
// Fetch user details
|
||||
$stmt = db()->prepare("SELECT * FROM users WHERE username = ?");
|
||||
$stmt->execute([$username]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
// Fetch user attendance
|
||||
$stmt = db()->prepare("SELECT attendance_date, status FROM attendance WHERE user_id = ? ORDER BY attendance_date DESC");
|
||||
$stmt->execute([$user['id']]);
|
||||
$attendance_records = $stmt->fetchAll();
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Employee Profile</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/css/custom.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="d-flex">
|
||||
<?php include 'sidebar.php'; ?>
|
||||
<div class="content p-4">
|
||||
<h1 class="mb-4">Employee Profile</h1>
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Profile Details</h5>
|
||||
<p><strong>Name:</strong> <?php echo htmlspecialchars($user['full_name']); ?></p>
|
||||
<p><strong>Username:</strong> <?php echo htmlspecialchars($user['username']); ?></p>
|
||||
<p><strong>Role:</strong> <?php echo htmlspecialchars($user['role']); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Attendance History</h5>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($attendance_records as $record): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($record['attendance_date']); ?></td>
|
||||
<td><?php echo htmlspecialchars($record['status']); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($attendance_records)): ?>
|
||||
<tr>
|
||||
<td colspan="2" class="text-center">No attendance records found.</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
35
sidebar.php
Normal file
35
sidebar.php
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
<div class="sidebar">
|
||||
<h4 class="mb-4 fw-bold">Attendance System</h4>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="index.php"><i class="bi bi-grid-fill me-2"></i> Dashboard</a>
|
||||
</li>
|
||||
<?php if(isset($_SESSION['role']) && $_SESSION['role'] == 'Admin'): ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="add_employee.php"><i class="bi bi-person-plus-fill me-2"></i> Add Employee</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="view_employees.php"><i class="bi bi-people-fill me-2"></i> View Employees</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if(isset($_SESSION['role']) && ($_SESSION['role'] == 'Admin' || $_SESSION['role'] == 'HR')):
|
||||
?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="mark_attendance.php"><i class="bi bi-calendar-check-fill me-2"></i> Mark Attendance</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="attendance_report.php"><i class="bi bi-file-earmark-bar-graph-fill me-2"></i> Attendance Report</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'leave_requests.php' || basename($_SERVER['PHP_SELF']) == 'submit_leave_request.php' ? 'active' : ''; ?>" href="leave_requests.php"><i class="bi bi-calendar-plus-fill me-2"></i> Leave Requests</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="profile.php"><i class="bi bi-person-circle me-2"></i> Profile</a>
|
||||
</li>
|
||||
<li class="nav-item mt-auto">
|
||||
<a class="nav-link" href="logout.php"><i class="bi bi-box-arrow-left me-2"></i> Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
119
submit_leave_request.php
Normal file
119
submit_leave_request.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$start_date = $end_date = $reason = '';
|
||||
$start_date_err = $end_date_err = $reason_err = '';
|
||||
$success_msg = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Validate start date
|
||||
if (empty(trim($_POST['start_date']))) {
|
||||
$start_date_err = 'Please enter a start date.';
|
||||
} else {
|
||||
$start_date = trim($_POST['start_date']);
|
||||
}
|
||||
|
||||
// Validate end date
|
||||
if (empty(trim($_POST['end_date']))) {
|
||||
$end_date_err = 'Please enter an end date.';
|
||||
} else {
|
||||
$end_date = trim($_POST['end_date']);
|
||||
}
|
||||
|
||||
// Validate reason
|
||||
if (empty(trim($_POST['reason']))) {
|
||||
$reason_err = 'Please provide a reason.';
|
||||
} else {
|
||||
$reason = trim($_POST['reason']);
|
||||
}
|
||||
|
||||
if (empty($start_date_err) && empty($end_date_err) && empty($reason_err)) {
|
||||
$sql = 'INSERT INTO leave_requests (employee_id, start_date, end_date, reason) VALUES (:employee_id, :start_date, :end_date, :reason)';
|
||||
if ($stmt = db()->prepare($sql)) {
|
||||
$stmt->bindParam(':employee_id', $_SESSION['id'], PDO::PARAM_INT);
|
||||
$stmt->bindParam(':start_date', $start_date, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':end_date', $end_date, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':reason', $reason, PDO::PARAM_STR);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$success_msg = 'Leave request submitted successfully!';
|
||||
|
||||
// Send email notification to Admins and HR
|
||||
require_once 'mail/MailService.php';
|
||||
$sql_users = "SELECT username FROM users WHERE role = 'Admin' OR role = 'HR'";
|
||||
$stmt_users = db()->query($sql_users);
|
||||
$recipients = $stmt_users->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
if (!empty($recipients)) {
|
||||
$subject = "New Leave Request Submitted";
|
||||
$body = "A new leave request has been submitted by {$_SESSION['username']}.<br><br>"
|
||||
. "<b>Start Date:</b> {$start_date}<br>"
|
||||
. "<b>End Date:</b> {$end_date}<br>"
|
||||
. "<b>Reason:</b> {$reason}<br><br>"
|
||||
. "Please log in to the system to approve or reject this request.";
|
||||
MailService::sendMail($recipients, $subject, $body, strip_tags($body));
|
||||
}
|
||||
|
||||
$start_date = $end_date = $reason = '';
|
||||
} else {
|
||||
echo 'Oops! Something went wrong. Please try again later.';
|
||||
}
|
||||
unset($stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Submit Leave Request - Employee Attendance System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.css">
|
||||
</head>
|
||||
<body>
|
||||
<?php include 'sidebar.php'; ?>
|
||||
<div class="main-content">
|
||||
<div class="container-fluid">
|
||||
<h1 class="mt-4">Submit Leave Request</h1>
|
||||
<p class="lead">Fill out the form to request time off.</p>
|
||||
|
||||
<?php if (!empty($success_msg)): ?>
|
||||
<div class="alert alert-success"><?php echo $success_msg; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post" class="mt-4 card p-4 bg-white border-0 shadow-sm">
|
||||
<div class="mb-3">
|
||||
<label for="start_date" class="form-label">Start Date</label>
|
||||
<input type="date" name="start_date" id="start_date" class="form-control <?php echo (!empty($start_date_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $start_date; ?>">
|
||||
<span class="invalid-feedback"><?php echo $start_date_err; ?></span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="end_date" class="form-label">End Date</label>
|
||||
<input type="date" name="end_date" id="end_date" class="form-control <?php echo (!empty($end_date_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $end_date; ?>">
|
||||
<span class="invalid-feedback"><?php echo $end_date_err; ?></span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="reason" class="form-label">Reason for Leave</label>
|
||||
<textarea name="reason" id="reason" class="form-control <?php echo (!empty($reason_err)) ? 'is-invalid' : ''; ?>" rows="3"><?php echo $reason; ?></textarea>
|
||||
<span class="invalid-feedback"><?php echo $reason_err; ?></span>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary">Submit Request</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
42
update_leave_status.php
Normal file
42
update_leave_status.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true || ($_SESSION['role'] !== 'Admin' && $_SESSION['role'] !== 'HR')) {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_GET['id']) && isset($_GET['status'])) {
|
||||
$id = $_GET['id'];
|
||||
$status = $_GET['status'];
|
||||
|
||||
if ($status === 'approved' || $status === 'rejected') {
|
||||
$sql = "UPDATE leave_requests SET status = :status WHERE id = :id";
|
||||
if ($stmt = db()->prepare($sql)) {
|
||||
$stmt->bindParam(':status', $status, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
|
||||
if ($stmt->execute()) {
|
||||
// Send email notification to the employee
|
||||
require_once 'mail/MailService.php';
|
||||
$sql_request = "SELECT lr.start_date, lr.end_date, u.username FROM leave_requests lr JOIN users u ON lr.employee_id = u.id WHERE lr.id = :id";
|
||||
$stmt_request = db()->prepare($sql_request);
|
||||
$stmt_request->bindParam(':id', $id, PDO::PARAM_INT);
|
||||
$stmt_request->execute();
|
||||
$request_data = $stmt_request->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($request_data) {
|
||||
$to = $request_data['username'];
|
||||
$subject = "Your Leave Request has been " . ucfirst($status);
|
||||
$body = "Your leave request from {$request_data['start_date']} to {$request_data['end_date']} has been <b>{$status}</b>.<br><br>"
|
||||
. "Log in to the system for more details.";
|
||||
MailService::sendMail($to, $subject, $body, strip_tags($body));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('location: leave_requests.php');
|
||||
exit;
|
||||
?>
|
||||
103
view_employees.php
Normal file
103
view_employees.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true || $_SESSION['role'] !== 'Admin') {
|
||||
header('location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$users = [];
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->query("SELECT id, username, role FROM users ORDER BY id DESC");
|
||||
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
// For a real app, you'd want to log this error
|
||||
die("Could not connect to the database or fetch users.");
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>View Employees - Employee Attendance System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.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=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="sidebar">
|
||||
<h4 class="mb-4 fw-bold">Attendance System</h4>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php"><i class="bi bi-grid-fill me-2"></i> Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="add_employee.php"><i class="bi bi-person-plus-fill me-2"></i> Add Employee</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="view_employees.php"><i class="bi bi-people-fill me-2"></i> View Employees</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#"><i class="bi bi-calendar-check-fill me-2"></i> Attendance</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#"><i class="bi bi-file-earmark-bar-graph-fill me-2"></i> Reports</a>
|
||||
</li>
|
||||
<li class="nav-item mt-auto">
|
||||
<a class="nav-link" href="logout.php"><i class="bi bi-box-arrow-left me-2"></i> Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="container-fluid">
|
||||
<h1 class="mt-4">View Employees</h1>
|
||||
<p class="lead">A list of all users in the system.</p>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<table class="table table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Username</th>
|
||||
<th scope="col">Role</th>
|
||||
<th scope="col">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($users)): ?>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center">No users found.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($users as $user): ?>
|
||||
<tr>
|
||||
<th scope="row"><?php echo htmlspecialchars($user['id']); ?></th>
|
||||
<td><?php echo htmlspecialchars($user['username']); ?></td>
|
||||
<td><?php echo htmlspecialchars($user['role']); ?></td>
|
||||
<td>
|
||||
<a href="edit_employee.php?id=<?php echo $user['id']; ?>" class="btn btn-sm btn-outline-primary"><i class="bi bi-pencil-square"></i></a>
|
||||
<a href="delete_employee.php?id=<?php echo $user['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('Are you sure you want to delete this employee?');"><i class="bi bi-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user