234 lines
8.8 KiB
PHP
234 lines
8.8 KiB
PHP
<?php
|
|
require_once 'auth_helper.php';
|
|
$user = get_user();
|
|
|
|
if (!$user) {
|
|
include 'landing.php';
|
|
exit;
|
|
}
|
|
|
|
if (in_array($user['role'], ['Admin', 'Adviser', 'Officer'])) {
|
|
include 'dashboard.php';
|
|
exit;
|
|
}
|
|
|
|
$pdo = db();
|
|
|
|
// Voter redirection logic
|
|
if ($user['role'] === 'Voter') {
|
|
// Find ongoing elections that this voter is assigned to
|
|
$stmt = $pdo->prepare("
|
|
SELECT e.* FROM elections e
|
|
JOIN election_assignments ea ON e.id = ea.election_id
|
|
WHERE ea.user_id = ?
|
|
AND e.status = 'Ongoing'
|
|
AND e.archived = FALSE
|
|
AND e.end_date_and_time > CURRENT_TIMESTAMP
|
|
");
|
|
$stmt->execute([$user['id']]);
|
|
$activeElections = $stmt->fetchAll();
|
|
|
|
// Filter out elections where the user has already voted
|
|
$votedElectionsStmt = $pdo->prepare("SELECT election_id FROM votes WHERE voter_id = ?");
|
|
$votedElectionsStmt->execute([$user['id']]);
|
|
$votedIds = $votedElectionsStmt->fetchAll(PDO::FETCH_COLUMN);
|
|
|
|
$eligibleElections = array_filter($activeElections, function($e) use ($votedIds) {
|
|
return !in_array($e['id'], $votedIds);
|
|
});
|
|
|
|
if (count($eligibleElections) === 1) {
|
|
$singleElection = reset($eligibleElections);
|
|
header("Location: ballot.php?id=" . $singleElection['id']);
|
|
exit;
|
|
}
|
|
|
|
// If no eligible elections but they were assigned to some active ones, they've already voted
|
|
if (count($eligibleElections) === 0 && count($activeElections) > 0) {
|
|
if (!isset($_GET['success']) && !isset($_GET['error'])) {
|
|
header("Location: index.php?error=already_voted");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// For voters, only show their assigned elections in the list
|
|
$elections = $activeElections;
|
|
} else {
|
|
$elections = $pdo->query("SELECT * FROM elections WHERE archived = FALSE ORDER BY created_at DESC")->fetchAll();
|
|
}
|
|
|
|
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Online Election System for Senior High School';
|
|
?>
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Election Dashboard | <?= htmlspecialchars($projectDescription) ?></title>
|
|
<meta name="description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<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">
|
|
<link rel="stylesheet" href="assets/css/style.css?v=<?= time() ?>">
|
|
</head>
|
|
<?php $isVotedModalActive = (isset($_GET['success']) && $_GET['success'] === 'voted') || (isset($_GET['error']) && $_GET['error'] === 'already_voted'); ?>
|
|
<body class="<?= ($user['theme'] ?? 'light') === 'dark' ? 'dark-theme' : '' ?>">
|
|
<nav class="navbar" <?= $isVotedModalActive ? 'style="display: none;"' : '' ?>>
|
|
<a href="index.php" class="brand">Click to Vote</a>
|
|
<div>
|
|
<span style="margin-right: 1rem; color: var(--text-muted);"><?= htmlspecialchars($user['name']) ?> (<?= $user['role'] ?>)</span>
|
|
<a href="logout.php" class="btn btn-outline">Logout</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container" <?= $isVotedModalActive ? 'style="display: none;"' : '' ?>>
|
|
<?php if (isset($_GET['success']) && $_GET['success'] !== 'voted'): ?>
|
|
<div style="background: #dcfce7; color: #166534; padding: 1rem; border-radius: var(--radius); border: 1px solid #bbf7d0; margin-bottom: 1.5rem; font-size: 0.875rem;">
|
|
Action completed successfully.
|
|
</div>
|
|
<?php endif; ?>
|
|
<div class="header-actions">
|
|
<div>
|
|
<h1 style="margin: 0; font-size: 1.5rem;">Elections</h1>
|
|
<p style="margin: 0; color: var(--text-muted);">Manage your school elections and voting sessions.</p>
|
|
</div>
|
|
<?php if (in_array($user['role'], ['Admin', 'Adviser', 'Officer'])): ?>
|
|
<a href="create_election.php" class="btn btn-primary">+ New Election</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<?php if (empty($elections)): ?>
|
|
<div style="text-align: center; padding: 2rem;">
|
|
<p style="color: var(--text-muted);">No elections found. Create your first election to get started.</p>
|
|
<?php if (in_array($user['role'], ['Admin', 'Adviser', 'Officer'])): ?>
|
|
<a href="create_election.php" class="btn btn-outline" style="margin-top: 1rem;">Setup Election</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Title</th>
|
|
<th>Status</th>
|
|
<th>Period</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($elections as $election): ?>
|
|
<tr>
|
|
<td>
|
|
<div style="font-weight: 600;"><?= htmlspecialchars($election['title']) ?></div>
|
|
<div style="font-size: 0.75rem; color: var(--text-muted);"><?= htmlspecialchars($election['description']) ?></div>
|
|
</td>
|
|
<td>
|
|
<span class="badge badge-<?= strtolower($election['status']) ?>">
|
|
<?= htmlspecialchars($election['status']) ?>
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<div style="font-size: 0.875rem;">
|
|
<?= date('M d, H:i', strtotime($election['start_date_and_time'])) ?> -
|
|
<?= date('M d, H:i', strtotime($election['end_date_and_time'])) ?>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<a href="view_election.php?id=<?= $election['id'] ?>" class="btn btn-outline" style="padding: 0.25rem 0.5rem; font-size: 0.75rem;">View</a>
|
|
<?php if ($election['status'] === 'Ongoing'): ?>
|
|
<a href="ballot.php?id=<?= $election['id'] ?>" class="btn btn-primary" style="padding: 0.25rem 0.5rem; font-size: 0.75rem; background: #166534;">Vote</a>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Voted Modal -->
|
|
<div id="votedModal" class="modal-overlay <?= (isset($_GET['success']) && $_GET['success'] === 'voted') || (isset($_GET['error']) && $_GET['error'] === 'already_voted') ? 'active' : '' ?>">
|
|
<div class="confirm-modal" style="text-align: center;">
|
|
<div class="modal-icon" style="background: #f0fdf4; color: #10b981; margin: 0 auto 24px;">
|
|
<svg style="width: 32px; height: 32px;" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>
|
|
</svg>
|
|
</div>
|
|
<h2>Already Voted</h2>
|
|
<p>You have already submitted your vote for this election. Thank you for participating!</p>
|
|
<div style="margin-top: 32px;">
|
|
<a href="logout.php" class="btn btn-primary" style="display: block; width: 100%; text-decoration: none; padding: 12px 0; background: #4f46e5; border-radius: 12px; font-weight: 700; color: white;">Back to Login</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
/* Modal Styles */
|
|
.modal-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(15, 23, 42, 0.6);
|
|
backdrop-filter: blur(4px);
|
|
z-index: 2000;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 20px;
|
|
}
|
|
|
|
.modal-overlay.active {
|
|
display: flex;
|
|
}
|
|
|
|
.confirm-modal {
|
|
background: white;
|
|
border-radius: 20px;
|
|
max-width: 450px;
|
|
width: 100%;
|
|
padding: 32px;
|
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
animation: modalIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
}
|
|
|
|
@keyframes modalIn {
|
|
from { transform: scale(0.9) translateY(20px); opacity: 0; }
|
|
to { transform: scale(1) translateY(0); opacity: 1; }
|
|
}
|
|
|
|
.modal-icon {
|
|
width: 64px;
|
|
height: 64px;
|
|
background: #eef2ff;
|
|
color: #4f46e5;
|
|
border-radius: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.confirm-modal h2 {
|
|
margin: 0 0 12px 0;
|
|
font-size: 1.5rem;
|
|
font-weight: 800;
|
|
color: #1e293b;
|
|
}
|
|
|
|
.confirm-modal p {
|
|
margin: 0 0 12px 0;
|
|
color: #64748b;
|
|
font-size: 1rem;
|
|
line-height: 1.6;
|
|
}
|
|
</style>
|
|
|
|
<footer style="text-align: center; color: var(--text-muted); padding: 2rem; <?= $isVotedModalActive ? 'display: none;' : '' ?>">
|
|
© <?= date('Y') ?> Click to Vote | High School Online Election System
|
|
</footer>
|
|
</body>
|
|
</html>
|