Spaces:
Sleeping
Sleeping
Upload 30 files
Browse files- .gitignore +48 -0
- README.md +88 -12
- admin.php +225 -0
- app.py +35 -0
- auth_check.php +124 -0
- create_domain_descriptions.php +112 -0
- db_connect.php +59 -0
- domain_projects.php +124 -0
- domain_utils.php +110 -0
- domains.php +97 -0
- footer.php +45 -0
- get_domain_fields.php +86 -0
- header.php +92 -0
- index.php +164 -0
- login.php +286 -0
- logout.php +36 -0
- my_projects.php +299 -0
- profile.php +280 -0
- project_add.php +337 -0
- project_delete.php +153 -0
- project_details.php +279 -0
- project_edit.php +292 -0
- project_manage.php +316 -0
- register.php +204 -0
- requirements.txt +4 -0
- runtime.txt +1 -0
- script.js +78 -0
- student_projects.php +328 -0
- students.php +201 -0
- styles.css +547 -0
.gitignore
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Python
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.py[cod]
|
| 4 |
+
*$py.class
|
| 5 |
+
*.so
|
| 6 |
+
.Python
|
| 7 |
+
env/
|
| 8 |
+
build/
|
| 9 |
+
develop-eggs/
|
| 10 |
+
dist/
|
| 11 |
+
downloads/
|
| 12 |
+
eggs/
|
| 13 |
+
.eggs/
|
| 14 |
+
lib/
|
| 15 |
+
lib64/
|
| 16 |
+
parts/
|
| 17 |
+
sdist/
|
| 18 |
+
var/
|
| 19 |
+
wheels/
|
| 20 |
+
*.egg-info/
|
| 21 |
+
.installed.cfg
|
| 22 |
+
*.egg
|
| 23 |
+
|
| 24 |
+
# Virtual Environment
|
| 25 |
+
venv/
|
| 26 |
+
ENV/
|
| 27 |
+
|
| 28 |
+
# IDE
|
| 29 |
+
.idea/
|
| 30 |
+
.vscode/
|
| 31 |
+
*.swp
|
| 32 |
+
*.swo
|
| 33 |
+
|
| 34 |
+
# OS
|
| 35 |
+
.DS_Store
|
| 36 |
+
Thumbs.db
|
| 37 |
+
|
| 38 |
+
# Logs
|
| 39 |
+
*.log
|
| 40 |
+
|
| 41 |
+
# Environment variables
|
| 42 |
+
.env
|
| 43 |
+
.env.local
|
| 44 |
+
.env.*.local
|
| 45 |
+
|
| 46 |
+
# Database
|
| 47 |
+
*.sql
|
| 48 |
+
*.sqlite
|
README.md
CHANGED
|
@@ -1,12 +1,88 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
-
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Domain Management System
|
| 2 |
+
|
| 3 |
+
A web-based platform to explore, search, and view projects across various domains, based on the DMS database.
|
| 4 |
+
|
| 5 |
+
## Features
|
| 6 |
+
|
| 7 |
+
- **Browse Domains**: View all available domains in the system and their associated projects.
|
| 8 |
+
- **Project Search**: Search for projects by name, description, domain, or type (Hardware/Software).
|
| 9 |
+
- **Project Details**: View detailed information about each project, including descriptions, contact information, and associated resources.
|
| 10 |
+
- **Student Information**: If the student table exists, search and view student information related to projects.
|
| 11 |
+
- **Dynamic Data Fetching**: The system automatically fetches data from parent tables, avoiding manual duplication of data.
|
| 12 |
+
- **Domain Descriptions**: Domain descriptions are automatically generated from the database or fallback to defaults.
|
| 13 |
+
|
| 14 |
+
## Setup Instructions
|
| 15 |
+
|
| 16 |
+
### Prerequisites
|
| 17 |
+
|
| 18 |
+
- Web server with PHP support (e.g., Apache, Nginx)
|
| 19 |
+
- MySQL/MariaDB database server
|
| 20 |
+
- PHP 7.0 or higher
|
| 21 |
+
|
| 22 |
+
### Database Setup
|
| 23 |
+
|
| 24 |
+
1. Create a new database named `dms` in your MySQL server:
|
| 25 |
+
```sql
|
| 26 |
+
CREATE DATABASE dms;
|
| 27 |
+
```
|
| 28 |
+
|
| 29 |
+
2. Import the SQL file (`dms (2).sql`) into your database:
|
| 30 |
+
- Using phpMyAdmin: Go to the Import tab, select the SQL file, and click "Go"
|
| 31 |
+
- Using MySQL command line:
|
| 32 |
+
```
|
| 33 |
+
mysql -u username -p dms < "dms (2).sql"
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
3. (Optional) Create domain descriptions table:
|
| 37 |
+
- Access the `create_domain_descriptions.php` script in your browser to create and populate the domain_descriptions table
|
| 38 |
+
- This step is optional but recommended for better organization of domain metadata
|
| 39 |
+
|
| 40 |
+
### Web Application Setup
|
| 41 |
+
|
| 42 |
+
1. Copy all files to your web server's document root (or a subdirectory).
|
| 43 |
+
2. Update the database connection details in `includes/db_connect.php` if needed.
|
| 44 |
+
3. Make sure your web server has permissions to read/write to the files.
|
| 45 |
+
4. Access the website through your web browser.
|
| 46 |
+
|
| 47 |
+
## Database Structure
|
| 48 |
+
|
| 49 |
+
The database consists of multiple tables:
|
| 50 |
+
|
| 51 |
+
- `domain_1` through `domain_12`: Tables containing projects from different domains
|
| 52 |
+
- `students_info`: Table containing student information (if available)
|
| 53 |
+
- `domain_descriptions`: Optional table for storing domain descriptions
|
| 54 |
+
|
| 55 |
+
Each domain table has a similar structure with fields like:
|
| 56 |
+
- `Domain_ID`
|
| 57 |
+
- `Project_ID`
|
| 58 |
+
- `Project_Name`/`Project _Name`
|
| 59 |
+
- `Email`
|
| 60 |
+
- `H/S` (Hardware/Software)
|
| 61 |
+
- `Description`
|
| 62 |
+
- `Links`
|
| 63 |
+
|
| 64 |
+
## Dynamic Data Handling
|
| 65 |
+
|
| 66 |
+
The system uses several utility functions to automatically fetch and process data:
|
| 67 |
+
|
| 68 |
+
- **Domain Descriptions**: Automatically fetched from the domain_descriptions table if it exists, otherwise falls back to default values
|
| 69 |
+
- **Project Names**: The system handles different column naming conventions across tables
|
| 70 |
+
- **Cross-Domain Search**: Searches can be performed across all domain tables simultaneously
|
| 71 |
+
- **Student-Project Association**: Student data is linked dynamically to projects for comprehensive viewing
|
| 72 |
+
|
| 73 |
+
## Usage
|
| 74 |
+
|
| 75 |
+
1. **Home Page**: View basic statistics and recent projects from all domains
|
| 76 |
+
2. **Domains Page**: Browse all domains and access their projects
|
| 77 |
+
3. **Projects Page**: Search for projects across all domains with advanced filtering
|
| 78 |
+
4. **Students Page**: Search for students by name, division, or domain (if the table exists)
|
| 79 |
+
|
| 80 |
+
## Troubleshooting
|
| 81 |
+
|
| 82 |
+
- If you encounter database connection errors, verify that the credentials in `includes/db_connect.php` are correct.
|
| 83 |
+
- Make sure that the `dms` database has been properly imported with all required tables.
|
| 84 |
+
- Check your PHP error logs if you're experiencing issues with the website.
|
| 85 |
+
|
| 86 |
+
## Credits
|
| 87 |
+
|
| 88 |
+
Created as a Database Management System project.
|
admin.php
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication check
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/auth_check.php';
|
| 5 |
+
|
| 6 |
+
// This page is for faculty only
|
| 7 |
+
requireFaculty();
|
| 8 |
+
|
| 9 |
+
$error = '';
|
| 10 |
+
$success = '';
|
| 11 |
+
|
| 12 |
+
// Get all users
|
| 13 |
+
$users = [];
|
| 14 |
+
$query = "SELECT * FROM users ORDER BY created_at DESC";
|
| 15 |
+
$result = $conn->query($query);
|
| 16 |
+
|
| 17 |
+
if ($result && $result->num_rows > 0) {
|
| 18 |
+
while ($row = $result->fetch_assoc()) {
|
| 19 |
+
$users[] = $row;
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// Handle user activation/deactivation
|
| 24 |
+
if (isset($_GET['action']) && isset($_GET['id'])) {
|
| 25 |
+
$action = $_GET['action'];
|
| 26 |
+
$user_id = (int)$_GET['id'];
|
| 27 |
+
|
| 28 |
+
// Can't modify yourself
|
| 29 |
+
if ($user_id === (int)$_SESSION['user_id']) {
|
| 30 |
+
$error = "You cannot modify your own account status.";
|
| 31 |
+
} else {
|
| 32 |
+
if ($action === 'activate') {
|
| 33 |
+
$status = 'active';
|
| 34 |
+
$success_msg = "User activated successfully.";
|
| 35 |
+
} elseif ($action === 'deactivate') {
|
| 36 |
+
$status = 'inactive';
|
| 37 |
+
$success_msg = "User deactivated successfully.";
|
| 38 |
+
} else {
|
| 39 |
+
$error = "Invalid action.";
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
if (empty($error)) {
|
| 43 |
+
$update_query = "UPDATE users SET status = ? WHERE id = ?";
|
| 44 |
+
$update_stmt = $conn->prepare($update_query);
|
| 45 |
+
$update_stmt->bind_param("si", $status, $user_id);
|
| 46 |
+
|
| 47 |
+
if ($update_stmt->execute()) {
|
| 48 |
+
$success = $success_msg;
|
| 49 |
+
|
| 50 |
+
// Refresh user list
|
| 51 |
+
$result = $conn->query($query);
|
| 52 |
+
$users = [];
|
| 53 |
+
if ($result && $result->num_rows > 0) {
|
| 54 |
+
while ($row = $result->fetch_assoc()) {
|
| 55 |
+
$users[] = $row;
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
} else {
|
| 59 |
+
$error = "Failed to update user status: " . $conn->error;
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// Count stats
|
| 66 |
+
$totalUsers = count($users);
|
| 67 |
+
$activeUsers = 0;
|
| 68 |
+
$inactiveUsers = 0;
|
| 69 |
+
$studentUsers = 0;
|
| 70 |
+
$facultyUsers = 0;
|
| 71 |
+
|
| 72 |
+
foreach ($users as $user) {
|
| 73 |
+
if ($user['status'] === 'active') $activeUsers++;
|
| 74 |
+
if ($user['status'] === 'inactive') $inactiveUsers++;
|
| 75 |
+
if ($user['user_type'] === 'student') $studentUsers++;
|
| 76 |
+
if ($user['user_type'] === 'faculty') $facultyUsers++;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
// Include header
|
| 80 |
+
include 'includes/header.php';
|
| 81 |
+
?>
|
| 82 |
+
|
| 83 |
+
<div class="row mb-4">
|
| 84 |
+
<div class="col-md-12">
|
| 85 |
+
<nav aria-label="breadcrumb">
|
| 86 |
+
<ol class="breadcrumb">
|
| 87 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 88 |
+
<li class="breadcrumb-item active">Admin Panel</li>
|
| 89 |
+
</ol>
|
| 90 |
+
</nav>
|
| 91 |
+
<h2><i class="fas fa-cogs me-2"></i> Admin Panel</h2>
|
| 92 |
+
<p class="lead">Manage users and system settings</p>
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
|
| 96 |
+
<?php if (!empty($error)): ?>
|
| 97 |
+
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
| 98 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 99 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 100 |
+
</div>
|
| 101 |
+
<?php endif; ?>
|
| 102 |
+
|
| 103 |
+
<?php if (!empty($success)): ?>
|
| 104 |
+
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
| 105 |
+
<i class="fas fa-check-circle me-2"></i> <?php echo $success; ?>
|
| 106 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 107 |
+
</div>
|
| 108 |
+
<?php endif; ?>
|
| 109 |
+
|
| 110 |
+
<div class="row mb-4">
|
| 111 |
+
<div class="col-md-3">
|
| 112 |
+
<div class="card text-center mb-3 shadow-sm">
|
| 113 |
+
<div class="card-body">
|
| 114 |
+
<i class="fas fa-users fa-3x mb-3 text-primary"></i>
|
| 115 |
+
<h5 class="card-title">Total Users</h5>
|
| 116 |
+
<p class="card-text display-4"><?php echo $totalUsers; ?></p>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
</div>
|
| 120 |
+
<div class="col-md-3">
|
| 121 |
+
<div class="card text-center mb-3 shadow-sm">
|
| 122 |
+
<div class="card-body">
|
| 123 |
+
<i class="fas fa-user-graduate fa-3x mb-3 text-success"></i>
|
| 124 |
+
<h5 class="card-title">Students</h5>
|
| 125 |
+
<p class="card-text display-4"><?php echo $studentUsers; ?></p>
|
| 126 |
+
</div>
|
| 127 |
+
</div>
|
| 128 |
+
</div>
|
| 129 |
+
<div class="col-md-3">
|
| 130 |
+
<div class="card text-center mb-3 shadow-sm">
|
| 131 |
+
<div class="card-body">
|
| 132 |
+
<i class="fas fa-chalkboard-teacher fa-3x mb-3 text-danger"></i>
|
| 133 |
+
<h5 class="card-title">Faculty</h5>
|
| 134 |
+
<p class="card-text display-4"><?php echo $facultyUsers; ?></p>
|
| 135 |
+
</div>
|
| 136 |
+
</div>
|
| 137 |
+
</div>
|
| 138 |
+
<div class="col-md-3">
|
| 139 |
+
<div class="card text-center mb-3 shadow-sm">
|
| 140 |
+
<div class="card-body">
|
| 141 |
+
<i class="fas fa-toggle-on fa-3x mb-3 text-warning"></i>
|
| 142 |
+
<h5 class="card-title">Active/Inactive</h5>
|
| 143 |
+
<p class="card-text display-4"><?php echo $activeUsers; ?> / <?php echo $inactiveUsers; ?></p>
|
| 144 |
+
</div>
|
| 145 |
+
</div>
|
| 146 |
+
</div>
|
| 147 |
+
</div>
|
| 148 |
+
|
| 149 |
+
<div class="row">
|
| 150 |
+
<div class="col-md-12">
|
| 151 |
+
<div class="card shadow-sm">
|
| 152 |
+
<div class="card-header bg-primary text-white">
|
| 153 |
+
<h5 class="mb-0"><i class="fas fa-users me-2"></i> User Management</h5>
|
| 154 |
+
</div>
|
| 155 |
+
<div class="card-body">
|
| 156 |
+
<?php if (count($users) > 0): ?>
|
| 157 |
+
<div class="table-responsive">
|
| 158 |
+
<table class="table table-striped table-hover">
|
| 159 |
+
<thead class="table-light">
|
| 160 |
+
<tr>
|
| 161 |
+
<th>ID</th>
|
| 162 |
+
<th>Username</th>
|
| 163 |
+
<th>Email</th>
|
| 164 |
+
<th>Type</th>
|
| 165 |
+
<th>Status</th>
|
| 166 |
+
<th>Created</th>
|
| 167 |
+
<th>Last Login</th>
|
| 168 |
+
<th>Actions</th>
|
| 169 |
+
</tr>
|
| 170 |
+
</thead>
|
| 171 |
+
<tbody>
|
| 172 |
+
<?php foreach ($users as $user): ?>
|
| 173 |
+
<tr>
|
| 174 |
+
<td><?php echo $user['id']; ?></td>
|
| 175 |
+
<td><?php echo htmlspecialchars($user['username']); ?></td>
|
| 176 |
+
<td><?php echo htmlspecialchars($user['email']); ?></td>
|
| 177 |
+
<td>
|
| 178 |
+
<span class="badge <?php echo $user['user_type'] === 'faculty' ? 'bg-danger' : 'bg-success'; ?>">
|
| 179 |
+
<?php echo ucfirst($user['user_type']); ?>
|
| 180 |
+
</span>
|
| 181 |
+
</td>
|
| 182 |
+
<td>
|
| 183 |
+
<span class="badge <?php echo $user['status'] === 'active' ? 'bg-success' : 'bg-secondary'; ?>">
|
| 184 |
+
<?php echo ucfirst($user['status']); ?>
|
| 185 |
+
</span>
|
| 186 |
+
</td>
|
| 187 |
+
<td><?php echo date('M d, Y', strtotime($user['created_at'])); ?></td>
|
| 188 |
+
<td><?php echo $user['last_login'] ? date('M d, Y H:i', strtotime($user['last_login'])) : 'Never'; ?></td>
|
| 189 |
+
<td>
|
| 190 |
+
<?php if ((int)$user['id'] !== (int)$_SESSION['user_id']): ?>
|
| 191 |
+
<?php if ($user['status'] === 'active'): ?>
|
| 192 |
+
<a href="admin.php?action=deactivate&id=<?php echo $user['id']; ?>" class="btn btn-sm btn-warning">
|
| 193 |
+
<i class="fas fa-toggle-off"></i> Deactivate
|
| 194 |
+
</a>
|
| 195 |
+
<?php else: ?>
|
| 196 |
+
<a href="admin.php?action=activate&id=<?php echo $user['id']; ?>" class="btn btn-sm btn-success">
|
| 197 |
+
<i class="fas fa-toggle-on"></i> Activate
|
| 198 |
+
</a>
|
| 199 |
+
<?php endif; ?>
|
| 200 |
+
<?php else: ?>
|
| 201 |
+
<span class="text-muted">Current User</span>
|
| 202 |
+
<?php endif; ?>
|
| 203 |
+
</td>
|
| 204 |
+
</tr>
|
| 205 |
+
<?php endforeach; ?>
|
| 206 |
+
</tbody>
|
| 207 |
+
</table>
|
| 208 |
+
</div>
|
| 209 |
+
<?php else: ?>
|
| 210 |
+
<div class="alert alert-info">
|
| 211 |
+
<i class="fas fa-info-circle me-2"></i> No users found in the database.
|
| 212 |
+
</div>
|
| 213 |
+
<?php endif; ?>
|
| 214 |
+
</div>
|
| 215 |
+
</div>
|
| 216 |
+
</div>
|
| 217 |
+
</div>
|
| 218 |
+
|
| 219 |
+
<?php
|
| 220 |
+
// Include footer
|
| 221 |
+
include 'includes/footer.php';
|
| 222 |
+
|
| 223 |
+
// Close connection
|
| 224 |
+
$conn->close();
|
| 225 |
+
?>
|
app.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Flask, send_from_directory
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
app = Flask(__name__)
|
| 5 |
+
|
| 6 |
+
# Serve static files
|
| 7 |
+
@app.route('/css/<path:filename>')
|
| 8 |
+
def serve_css(filename):
|
| 9 |
+
return send_from_directory('css', filename)
|
| 10 |
+
|
| 11 |
+
@app.route('/js/<path:filename>')
|
| 12 |
+
def serve_js(filename):
|
| 13 |
+
return send_from_directory('js', filename)
|
| 14 |
+
|
| 15 |
+
@app.route('/includes/<path:filename>')
|
| 16 |
+
def serve_includes(filename):
|
| 17 |
+
return send_from_directory('includes', filename)
|
| 18 |
+
|
| 19 |
+
@app.route('/ajax/<path:filename>')
|
| 20 |
+
def serve_ajax(filename):
|
| 21 |
+
return send_from_directory('ajax', filename)
|
| 22 |
+
|
| 23 |
+
# Serve PHP files
|
| 24 |
+
@app.route('/')
|
| 25 |
+
def serve_index():
|
| 26 |
+
return send_from_directory('.', 'index.php')
|
| 27 |
+
|
| 28 |
+
@app.route('/<path:filename>')
|
| 29 |
+
def serve_php(filename):
|
| 30 |
+
if filename.endswith('.php'):
|
| 31 |
+
return send_from_directory('.', filename)
|
| 32 |
+
return "Not found", 404
|
| 33 |
+
|
| 34 |
+
if __name__ == '__main__':
|
| 35 |
+
app.run(host='0.0.0.0', port=7860)
|
auth_check.php
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Authentication Check
|
| 4 |
+
*
|
| 5 |
+
* This file checks if a user is logged in and redirects if necessary.
|
| 6 |
+
* It also provides functions for authentication-related operations.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
// Start session if not already started
|
| 10 |
+
if (session_status() === PHP_SESSION_NONE) {
|
| 11 |
+
session_start();
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
/**
|
| 15 |
+
* Check if user is logged in
|
| 16 |
+
*
|
| 17 |
+
* @return boolean True if user is logged in, false otherwise
|
| 18 |
+
*/
|
| 19 |
+
function isLoggedIn() {
|
| 20 |
+
return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
/**
|
| 24 |
+
* Check if current user is a faculty member
|
| 25 |
+
*
|
| 26 |
+
* @return boolean True if user is faculty, false otherwise
|
| 27 |
+
*/
|
| 28 |
+
function isFaculty() {
|
| 29 |
+
return isLoggedIn() && $_SESSION['user_type'] === 'faculty';
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
/**
|
| 33 |
+
* Check if current user is a student
|
| 34 |
+
*
|
| 35 |
+
* @return boolean True if user is a student, false otherwise
|
| 36 |
+
*/
|
| 37 |
+
function isStudent() {
|
| 38 |
+
return isLoggedIn() && $_SESSION['user_type'] === 'student';
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
/**
|
| 42 |
+
* Redirect non-logged in users to login page
|
| 43 |
+
*
|
| 44 |
+
* @param string $message Optional message to display after redirect
|
| 45 |
+
* @return void
|
| 46 |
+
*/
|
| 47 |
+
function requireLogin($message = 'Please login to access this page.') {
|
| 48 |
+
if (!isLoggedIn()) {
|
| 49 |
+
$_SESSION['auth_message'] = $message;
|
| 50 |
+
header('Location: login.php');
|
| 51 |
+
exit;
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
/**
|
| 56 |
+
* Redirect non-faculty users
|
| 57 |
+
*
|
| 58 |
+
* @param string $message Optional message to display after redirect
|
| 59 |
+
* @return void
|
| 60 |
+
*/
|
| 61 |
+
function requireFaculty($message = 'Faculty access required.') {
|
| 62 |
+
requireLogin();
|
| 63 |
+
|
| 64 |
+
if (!isFaculty()) {
|
| 65 |
+
$_SESSION['auth_message'] = $message;
|
| 66 |
+
header('Location: index.php');
|
| 67 |
+
exit;
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
/**
|
| 72 |
+
* Require user to be student to access page
|
| 73 |
+
* Redirects to index page if not student
|
| 74 |
+
*/
|
| 75 |
+
function requireStudent() {
|
| 76 |
+
requireLogin();
|
| 77 |
+
if (!isStudent()) {
|
| 78 |
+
header("Location: index.php");
|
| 79 |
+
exit;
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* Get user ID from session
|
| 85 |
+
*
|
| 86 |
+
* @return mixed User ID if logged in, null otherwise
|
| 87 |
+
*/
|
| 88 |
+
function getCurrentUserId() {
|
| 89 |
+
return isLoggedIn() ? $_SESSION['user_id'] : null;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
/**
|
| 93 |
+
* Get username from session
|
| 94 |
+
*
|
| 95 |
+
* @return mixed Username if logged in, null otherwise
|
| 96 |
+
*/
|
| 97 |
+
function getCurrentUsername() {
|
| 98 |
+
return isLoggedIn() ? $_SESSION['username'] : null;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
/**
|
| 102 |
+
* Get user type from session
|
| 103 |
+
*
|
| 104 |
+
* @return mixed User type if logged in, null otherwise
|
| 105 |
+
*/
|
| 106 |
+
function getCurrentUserType() {
|
| 107 |
+
return isLoggedIn() ? $_SESSION['user_type'] : null;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
/**
|
| 111 |
+
* Update the last login time for a user
|
| 112 |
+
*/
|
| 113 |
+
function updateLastLogin($conn, $user_id) {
|
| 114 |
+
$query = "UPDATE users SET last_login = NOW() WHERE id = ?";
|
| 115 |
+
$stmt = $conn->prepare($query);
|
| 116 |
+
$stmt->bind_param("i", $user_id);
|
| 117 |
+
$stmt->execute();
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
// Define variables to use in header
|
| 121 |
+
$is_logged_in = isLoggedIn();
|
| 122 |
+
$is_faculty = isFaculty();
|
| 123 |
+
$is_student = isStudent();
|
| 124 |
+
?>
|
create_domain_descriptions.php
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Domain Descriptions Table Creation
|
| 4 |
+
*
|
| 5 |
+
* This script creates a domain_descriptions table and populates it with
|
| 6 |
+
* descriptions for each domain, fetching domain IDs from existing domain tables.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
// Include database connection
|
| 10 |
+
require_once 'includes/db_connect.php';
|
| 11 |
+
require_once 'includes/domain_utils.php';
|
| 12 |
+
|
| 13 |
+
// Check if table already exists
|
| 14 |
+
$checkTableQuery = "SHOW TABLES LIKE 'domain_descriptions'";
|
| 15 |
+
$tableExists = $conn->query($checkTableQuery)->num_rows > 0;
|
| 16 |
+
|
| 17 |
+
if ($tableExists) {
|
| 18 |
+
// Drop the existing table if needed
|
| 19 |
+
$dropTableQuery = "DROP TABLE domain_descriptions";
|
| 20 |
+
if ($conn->query($dropTableQuery) === TRUE) {
|
| 21 |
+
echo "Existing domain_descriptions table dropped successfully.<br>";
|
| 22 |
+
} else {
|
| 23 |
+
echo "Error dropping table: " . $conn->error . "<br>";
|
| 24 |
+
exit;
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
// Create domain_descriptions table
|
| 29 |
+
$createTableQuery = "CREATE TABLE domain_descriptions (
|
| 30 |
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
| 31 |
+
Domain_ID VARCHAR(10) NOT NULL UNIQUE,
|
| 32 |
+
Description VARCHAR(100) NOT NULL,
|
| 33 |
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
| 34 |
+
)";
|
| 35 |
+
|
| 36 |
+
if ($conn->query($createTableQuery) === TRUE) {
|
| 37 |
+
echo "Domain descriptions table created successfully.<br>";
|
| 38 |
+
} else {
|
| 39 |
+
echo "Error creating table: " . $conn->error . "<br>";
|
| 40 |
+
exit;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
// Default descriptions for all domains
|
| 44 |
+
$defaultDescriptions = [
|
| 45 |
+
'1' => 'Agriculture',
|
| 46 |
+
'2' => 'Energy',
|
| 47 |
+
'3' => 'IoT & Automation',
|
| 48 |
+
'4' => 'Healthcare',
|
| 49 |
+
'5' => 'Transportation',
|
| 50 |
+
'6' => 'Smart City',
|
| 51 |
+
'7' => 'Education',
|
| 52 |
+
'8' => 'Environment',
|
| 53 |
+
'9' => 'Cybersecurity',
|
| 54 |
+
'10' => 'Fintech',
|
| 55 |
+
'11' => 'E-Commerce',
|
| 56 |
+
'12' => 'Other'
|
| 57 |
+
];
|
| 58 |
+
|
| 59 |
+
// Get all domain tables
|
| 60 |
+
$domainTables = getDomainTables($conn);
|
| 61 |
+
$insertedDomains = [];
|
| 62 |
+
|
| 63 |
+
// Get domain IDs from existing tables
|
| 64 |
+
foreach ($domainTables as $domainTable) {
|
| 65 |
+
$domainNumber = str_replace('domain_', '', $domainTable);
|
| 66 |
+
$domainIdQuery = "SELECT DISTINCT Domain_ID FROM $domainTable LIMIT 1";
|
| 67 |
+
$domainIdResult = $conn->query($domainIdQuery);
|
| 68 |
+
|
| 69 |
+
if ($domainIdResult && $domainIdResult->num_rows > 0) {
|
| 70 |
+
$domainId = $domainIdResult->fetch_assoc()['Domain_ID'];
|
| 71 |
+
$description = isset($defaultDescriptions[$domainNumber]) ? $defaultDescriptions[$domainNumber] : 'Domain ' . $domainNumber;
|
| 72 |
+
|
| 73 |
+
// Insert into domain_descriptions table
|
| 74 |
+
$insertQuery = "INSERT INTO domain_descriptions (Domain_ID, Description) VALUES (?, ?)";
|
| 75 |
+
$stmt = $conn->prepare($insertQuery);
|
| 76 |
+
$stmt->bind_param("ss", $domainId, $description);
|
| 77 |
+
|
| 78 |
+
if ($stmt->execute()) {
|
| 79 |
+
echo "Added description for $domainId: $description<br>";
|
| 80 |
+
$insertedDomains[] = $domainId;
|
| 81 |
+
} else {
|
| 82 |
+
echo "Error adding description for $domainId: " . $stmt->error . "<br>";
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
$stmt->close();
|
| 86 |
+
}
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
// Insert any missing domains from our default list
|
| 90 |
+
foreach ($defaultDescriptions as $domainNumber => $description) {
|
| 91 |
+
$domainId = "D-" . str_pad($domainNumber, 2, '0', STR_PAD_LEFT);
|
| 92 |
+
|
| 93 |
+
if (!in_array($domainId, $insertedDomains)) {
|
| 94 |
+
$insertQuery = "INSERT INTO domain_descriptions (Domain_ID, Description) VALUES (?, ?)";
|
| 95 |
+
$stmt = $conn->prepare($insertQuery);
|
| 96 |
+
$stmt->bind_param("ss", $domainId, $description);
|
| 97 |
+
|
| 98 |
+
if ($stmt->execute()) {
|
| 99 |
+
echo "Added description for $domainId: $description (from defaults)<br>";
|
| 100 |
+
} else {
|
| 101 |
+
echo "Error adding description for $domainId: " . $stmt->error . "<br>";
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
$stmt->close();
|
| 105 |
+
}
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
echo "<br>Domain descriptions setup complete.";
|
| 109 |
+
|
| 110 |
+
// Close connection
|
| 111 |
+
$conn->close();
|
| 112 |
+
?>
|
db_connect.php
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Database Connection
|
| 4 |
+
*
|
| 5 |
+
* This file establishes a secure connection to the MySQL database
|
| 6 |
+
* and handles any connection errors.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
// Start session if not already started
|
| 10 |
+
if (session_status() === PHP_SESSION_NONE) {
|
| 11 |
+
session_start();
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
// Database configuration
|
| 15 |
+
$db_config = [
|
| 16 |
+
'host' => 'localhost',
|
| 17 |
+
'username' => 'root',
|
| 18 |
+
'password' => '',
|
| 19 |
+
'database' => 'dms'
|
| 20 |
+
];
|
| 21 |
+
|
| 22 |
+
// Error handling
|
| 23 |
+
$error_message = '';
|
| 24 |
+
|
| 25 |
+
// Create connection
|
| 26 |
+
try {
|
| 27 |
+
$conn = new mysqli(
|
| 28 |
+
$db_config['host'],
|
| 29 |
+
$db_config['username'],
|
| 30 |
+
$db_config['password'],
|
| 31 |
+
$db_config['database']
|
| 32 |
+
);
|
| 33 |
+
|
| 34 |
+
// Check connection
|
| 35 |
+
if ($conn->connect_error) {
|
| 36 |
+
throw new Exception("Connection failed: " . $conn->connect_error);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
// Set charset to ensure proper encoding
|
| 40 |
+
$conn->set_charset("utf8mb4");
|
| 41 |
+
|
| 42 |
+
} catch (Exception $e) {
|
| 43 |
+
$error_message = $e->getMessage();
|
| 44 |
+
|
| 45 |
+
// Log the error
|
| 46 |
+
error_log("Database Connection Error: " . $error_message);
|
| 47 |
+
|
| 48 |
+
// Display user-friendly message
|
| 49 |
+
echo '
|
| 50 |
+
<div style="margin: 20px; padding: 20px; border: 1px solid #dc3545; border-radius: 5px; background-color: #f8d7da; color: #721c24;">
|
| 51 |
+
<h3>Database Connection Error</h3>
|
| 52 |
+
<p>We\'re having trouble connecting to the database. Please try again later.</p>
|
| 53 |
+
<p>If the problem persists, please contact the system administrator.</p>
|
| 54 |
+
</div>';
|
| 55 |
+
|
| 56 |
+
// Stop script execution
|
| 57 |
+
die();
|
| 58 |
+
}
|
| 59 |
+
?>
|
domain_projects.php
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Validate domain parameter
|
| 8 |
+
if (!isset($_GET['domain']) || !is_numeric($_GET['domain'])) {
|
| 9 |
+
header("Location: domains.php");
|
| 10 |
+
exit;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
$domainNumber = $_GET['domain'];
|
| 14 |
+
$domainTable = "domain_" . $domainNumber;
|
| 15 |
+
|
| 16 |
+
// Check if the domain table exists
|
| 17 |
+
$tableCheckQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 18 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 19 |
+
|
| 20 |
+
if (!$tableExists) {
|
| 21 |
+
header("Location: domains.php");
|
| 22 |
+
exit;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
// Get domain descriptions
|
| 26 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 27 |
+
$domainDescription = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : "Domain $domainNumber";
|
| 28 |
+
|
| 29 |
+
// Get the correct project name field for this domain
|
| 30 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 31 |
+
|
| 32 |
+
// Get projects for this domain
|
| 33 |
+
$projectsQuery = "SELECT * FROM $domainTable ORDER BY Project_ID";
|
| 34 |
+
$projectsResult = $conn->query($projectsQuery);
|
| 35 |
+
|
| 36 |
+
// Include header
|
| 37 |
+
include 'includes/header.php';
|
| 38 |
+
?>
|
| 39 |
+
|
| 40 |
+
<div class="row mb-4">
|
| 41 |
+
<div class="col-md-12">
|
| 42 |
+
<nav aria-label="breadcrumb">
|
| 43 |
+
<ol class="breadcrumb">
|
| 44 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 45 |
+
<li class="breadcrumb-item"><a href="domains.php">Domains</a></li>
|
| 46 |
+
<li class="breadcrumb-item active">Domain <?php echo $domainNumber; ?> Projects</li>
|
| 47 |
+
</ol>
|
| 48 |
+
</nav>
|
| 49 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 50 |
+
<h2><i class="fas fa-layer-group me-2"></i> Projects in Domain <?php echo $domainNumber; ?></h2>
|
| 51 |
+
<?php if ($is_faculty): ?>
|
| 52 |
+
<div>
|
| 53 |
+
<a href="project_add.php?domain=<?php echo urlencode($domainNumber); ?>" class="btn btn-primary">
|
| 54 |
+
<i class="fas fa-plus-circle me-1"></i> Add Project
|
| 55 |
+
</a>
|
| 56 |
+
<a href="project_manage.php?domain=<?php echo urlencode($domainNumber); ?>" class="btn btn-secondary">
|
| 57 |
+
<i class="fas fa-cog me-1"></i> Manage Projects
|
| 58 |
+
</a>
|
| 59 |
+
</div>
|
| 60 |
+
<?php endif; ?>
|
| 61 |
+
</div>
|
| 62 |
+
<p class="lead"><?php echo htmlspecialchars($domainDescription); ?></p>
|
| 63 |
+
</div>
|
| 64 |
+
</div>
|
| 65 |
+
|
| 66 |
+
<div class="row">
|
| 67 |
+
<?php if ($projectsResult && $projectsResult->num_rows > 0): ?>
|
| 68 |
+
<?php while ($project = $projectsResult->fetch_assoc()): ?>
|
| 69 |
+
<div class="col-md-6 col-lg-4 mb-4">
|
| 70 |
+
<div class="card h-100 shadow-sm <?php echo (isset($project['H/S']) && strtolower($project['H/S']) === 'h') ? 'hardware' : 'software'; ?> project-card">
|
| 71 |
+
<div class="card-body">
|
| 72 |
+
<h5 class="card-title"><?php echo htmlspecialchars($project[$projectNameField]); ?></h5>
|
| 73 |
+
<?php if (isset($project['H/S'])): ?>
|
| 74 |
+
<h6 class="card-subtitle mb-2 text-muted">
|
| 75 |
+
<span class="badge bg-<?php echo strtolower($project['H/S']) === 'h' ? 'warning' : 'info'; ?>">
|
| 76 |
+
<?php echo strtolower($project['H/S']) === 'h' ? 'Hardware' : 'Software'; ?>
|
| 77 |
+
</span>
|
| 78 |
+
</h6>
|
| 79 |
+
<?php endif; ?>
|
| 80 |
+
<p class="card-text">
|
| 81 |
+
<?php if (isset($project['Description'])): ?>
|
| 82 |
+
<?php echo (strlen($project['Description']) > 100) ? htmlspecialchars(substr($project['Description'], 0, 100)) . '...' : htmlspecialchars($project['Description']); ?>
|
| 83 |
+
<?php else: ?>
|
| 84 |
+
<em>No description available</em>
|
| 85 |
+
<?php endif; ?>
|
| 86 |
+
</p>
|
| 87 |
+
</div>
|
| 88 |
+
<div class="card-footer bg-transparent d-flex justify-content-between align-items-center">
|
| 89 |
+
<a href="project_details.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-sm btn-primary">
|
| 90 |
+
<i class="fas fa-info-circle me-1"></i> Details
|
| 91 |
+
</a>
|
| 92 |
+
<?php if ($is_faculty): ?>
|
| 93 |
+
<div class="btn-group btn-group-sm">
|
| 94 |
+
<a href="project_edit.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-outline-success" title="Edit Project">
|
| 95 |
+
<i class="fas fa-edit"></i>
|
| 96 |
+
</a>
|
| 97 |
+
<a href="project_delete.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-outline-danger" title="Delete Project">
|
| 98 |
+
<i class="fas fa-trash-alt"></i>
|
| 99 |
+
</a>
|
| 100 |
+
</div>
|
| 101 |
+
<?php endif; ?>
|
| 102 |
+
</div>
|
| 103 |
+
</div>
|
| 104 |
+
</div>
|
| 105 |
+
<?php endwhile; ?>
|
| 106 |
+
<?php else: ?>
|
| 107 |
+
<div class="col-md-12">
|
| 108 |
+
<div class="alert alert-info">
|
| 109 |
+
<i class="fas fa-info-circle me-2"></i> No projects found in this domain.
|
| 110 |
+
<?php if ($is_faculty): ?>
|
| 111 |
+
<a href="project_add.php?domain=<?php echo urlencode($domainNumber); ?>" class="alert-link">Add a project</a> to get started.
|
| 112 |
+
<?php endif; ?>
|
| 113 |
+
</div>
|
| 114 |
+
</div>
|
| 115 |
+
<?php endif; ?>
|
| 116 |
+
</div>
|
| 117 |
+
|
| 118 |
+
<?php
|
| 119 |
+
// Include footer
|
| 120 |
+
include 'includes/footer.php';
|
| 121 |
+
|
| 122 |
+
// Close connection
|
| 123 |
+
$conn->close();
|
| 124 |
+
?>
|
domain_utils.php
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Domain Utilities
|
| 4 |
+
*
|
| 5 |
+
* This file contains utility functions for handling domain data
|
| 6 |
+
* to avoid code duplication across multiple pages.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Get domain descriptions from database or fallback to static list
|
| 11 |
+
*
|
| 12 |
+
* @param mysqli $conn Database connection
|
| 13 |
+
* @return array Domain descriptions with key as domain number
|
| 14 |
+
*/
|
| 15 |
+
function getDomainDescriptions($conn) {
|
| 16 |
+
$domainDescriptions = [];
|
| 17 |
+
|
| 18 |
+
// Check if domain_descriptions table exists
|
| 19 |
+
$domainDescTableQuery = "SHOW TABLES LIKE 'domain_descriptions'";
|
| 20 |
+
$domainDescTableExists = $conn->query($domainDescTableQuery)->num_rows > 0;
|
| 21 |
+
|
| 22 |
+
if ($domainDescTableExists) {
|
| 23 |
+
// Fetch descriptions from the domain_descriptions table
|
| 24 |
+
$domainDescQuery = "SELECT Domain_ID, Description FROM domain_descriptions";
|
| 25 |
+
$domainDescResult = $conn->query($domainDescQuery);
|
| 26 |
+
|
| 27 |
+
if ($domainDescResult && $domainDescResult->num_rows > 0) {
|
| 28 |
+
while ($desc = $domainDescResult->fetch_assoc()) {
|
| 29 |
+
$domainId = str_replace('D-', '', $desc['Domain_ID']);
|
| 30 |
+
$domainDescriptions[$domainId] = $desc['Description'];
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// If we don't have descriptions from the database, use our static list
|
| 36 |
+
if (empty($domainDescriptions)) {
|
| 37 |
+
$domainDescriptions = [
|
| 38 |
+
'1' => 'Agriculture',
|
| 39 |
+
'2' => 'Energy',
|
| 40 |
+
'3' => 'IoT & Automation',
|
| 41 |
+
'4' => 'Healthcare',
|
| 42 |
+
'5' => 'Transportation',
|
| 43 |
+
'6' => 'Smart City',
|
| 44 |
+
'7' => 'Education',
|
| 45 |
+
'8' => 'Environment',
|
| 46 |
+
'9' => 'Cybersecurity',
|
| 47 |
+
'10' => 'Fintech',
|
| 48 |
+
'11' => 'E-Commerce',
|
| 49 |
+
'12' => 'Other'
|
| 50 |
+
];
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
return $domainDescriptions;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
/**
|
| 57 |
+
* Get all domain tables from the database
|
| 58 |
+
*
|
| 59 |
+
* @param mysqli $conn Database connection
|
| 60 |
+
* @return array List of domain table names
|
| 61 |
+
*/
|
| 62 |
+
function getDomainTables($conn) {
|
| 63 |
+
$domainTables = [];
|
| 64 |
+
|
| 65 |
+
$tablesQuery = "SHOW TABLES LIKE 'domain_%'";
|
| 66 |
+
$tablesResult = $conn->query($tablesQuery);
|
| 67 |
+
|
| 68 |
+
if ($tablesResult && $tablesResult->num_rows > 0) {
|
| 69 |
+
while ($table = $tablesResult->fetch_array()) {
|
| 70 |
+
$domainTables[] = $table[0];
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
return $domainTables;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
/**
|
| 78 |
+
* Get total project count across all domains
|
| 79 |
+
*
|
| 80 |
+
* @param mysqli $conn Database connection
|
| 81 |
+
* @return int Total project count
|
| 82 |
+
*/
|
| 83 |
+
function getTotalProjectCount($conn) {
|
| 84 |
+
$projectCount = 0;
|
| 85 |
+
$domainTables = getDomainTables($conn);
|
| 86 |
+
|
| 87 |
+
foreach ($domainTables as $domainTable) {
|
| 88 |
+
$countQuery = "SELECT COUNT(*) as count FROM $domainTable";
|
| 89 |
+
$countResult = $conn->query($countQuery);
|
| 90 |
+
if ($countResult && $countResult->num_rows > 0) {
|
| 91 |
+
$projectCount += $countResult->fetch_assoc()['count'];
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
return $projectCount;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
/**
|
| 99 |
+
* Get the correct project name field for a given domain table
|
| 100 |
+
*
|
| 101 |
+
* @param mysqli $conn Database connection
|
| 102 |
+
* @param string $tableName The domain table name
|
| 103 |
+
* @return string The correct field name for project name
|
| 104 |
+
*/
|
| 105 |
+
function getProjectNameField($conn, $tableName) {
|
| 106 |
+
$columnCheckQuery = "SHOW COLUMNS FROM $tableName LIKE 'Project_Name'";
|
| 107 |
+
$columnExists = $conn->query($columnCheckQuery)->num_rows > 0;
|
| 108 |
+
return $columnExists ? 'Project_Name' : 'Project _Name';
|
| 109 |
+
}
|
| 110 |
+
?>
|
domains.php
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Get domain descriptions
|
| 8 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 9 |
+
|
| 10 |
+
// Get all domain tables and sort them numerically
|
| 11 |
+
$domainTables = getDomainTables($conn);
|
| 12 |
+
usort($domainTables, function($a, $b) {
|
| 13 |
+
$numA = intval(preg_replace('/[^0-9]/', '', $a));
|
| 14 |
+
$numB = intval(preg_replace('/[^0-9]/', '', $b));
|
| 15 |
+
return $numA - $numB;
|
| 16 |
+
});
|
| 17 |
+
|
| 18 |
+
// Include header
|
| 19 |
+
include 'includes/header.php';
|
| 20 |
+
?>
|
| 21 |
+
|
| 22 |
+
<div class="row mb-4">
|
| 23 |
+
<div class="col-md-12">
|
| 24 |
+
<nav aria-label="breadcrumb">
|
| 25 |
+
<ol class="breadcrumb">
|
| 26 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 27 |
+
<li class="breadcrumb-item active">Domains</li>
|
| 28 |
+
</ol>
|
| 29 |
+
</nav>
|
| 30 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 31 |
+
<h2><i class="fas fa-layer-group me-2"></i> Project Domains</h2>
|
| 32 |
+
</div>
|
| 33 |
+
<p class="lead">Browse project domains to find projects in different areas of interest.</p>
|
| 34 |
+
</div>
|
| 35 |
+
</div>
|
| 36 |
+
|
| 37 |
+
<div class="row">
|
| 38 |
+
<?php foreach ($domainTables as $domainTable):
|
| 39 |
+
// Extract domain number from table name
|
| 40 |
+
preg_match('/domain_(\d+)/', $domainTable, $matches);
|
| 41 |
+
if (isset($matches[1])):
|
| 42 |
+
$domainNumber = $matches[1];
|
| 43 |
+
|
| 44 |
+
// Get project count for this domain
|
| 45 |
+
$countQuery = "SELECT COUNT(*) as count FROM $domainTable";
|
| 46 |
+
$countResult = $conn->query($countQuery);
|
| 47 |
+
$projectCount = $countResult->fetch_assoc()['count'];
|
| 48 |
+
|
| 49 |
+
// Get domain description
|
| 50 |
+
$domainDescription = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : "Domain $domainNumber";
|
| 51 |
+
?>
|
| 52 |
+
<div class="col-md-6 col-lg-4 mb-4">
|
| 53 |
+
<div class="card h-100 shadow-sm domain-card">
|
| 54 |
+
<div class="card-header bg-primary text-white">
|
| 55 |
+
<h5 class="mb-0">Domain <?php echo htmlspecialchars($domainNumber); ?></h5>
|
| 56 |
+
</div>
|
| 57 |
+
<div class="card-body">
|
| 58 |
+
<p class="card-text"><?php echo htmlspecialchars($domainDescription); ?></p>
|
| 59 |
+
<div class="d-flex justify-content-between align-items-end mt-3">
|
| 60 |
+
<span class="badge bg-secondary fs-6">
|
| 61 |
+
<i class="fas fa-clipboard-list me-1"></i> <?php echo $projectCount; ?> Project<?php echo $projectCount != 1 ? 's' : ''; ?>
|
| 62 |
+
</span>
|
| 63 |
+
<div>
|
| 64 |
+
<a href="domain_projects.php?domain=<?php echo urlencode($domainNumber); ?>" class="btn btn-outline-primary">
|
| 65 |
+
<i class="fas fa-eye me-1"></i> View Projects
|
| 66 |
+
</a>
|
| 67 |
+
<?php if ($is_faculty): ?>
|
| 68 |
+
<a href="project_add.php?domain=<?php echo urlencode($domainNumber); ?>" class="btn btn-outline-success">
|
| 69 |
+
<i class="fas fa-plus-circle me-1"></i> Add Project
|
| 70 |
+
</a>
|
| 71 |
+
<?php endif; ?>
|
| 72 |
+
</div>
|
| 73 |
+
</div>
|
| 74 |
+
</div>
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
<?php
|
| 78 |
+
endif;
|
| 79 |
+
endforeach;
|
| 80 |
+
|
| 81 |
+
if (count($domainTables) == 0):
|
| 82 |
+
?>
|
| 83 |
+
<div class="col-md-12">
|
| 84 |
+
<div class="alert alert-info">
|
| 85 |
+
<i class="fas fa-info-circle me-2"></i> No domains found in the database.
|
| 86 |
+
</div>
|
| 87 |
+
</div>
|
| 88 |
+
<?php endif; ?>
|
| 89 |
+
</div>
|
| 90 |
+
|
| 91 |
+
<?php
|
| 92 |
+
// Include footer
|
| 93 |
+
include 'includes/footer.php';
|
| 94 |
+
|
| 95 |
+
// Close connection
|
| 96 |
+
$conn->close();
|
| 97 |
+
?>
|
footer.php
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
</main>
|
| 2 |
+
</div>
|
| 3 |
+
|
| 4 |
+
<footer class="bg-dark text-white py-4 mt-5">
|
| 5 |
+
<div class="container">
|
| 6 |
+
<div class="row">
|
| 7 |
+
<div class="col-md-6">
|
| 8 |
+
<h5><i class="fas fa-database me-2"></i> Domain Management System</h5>
|
| 9 |
+
<p>A comprehensive platform for managing project domains, student information, and project details.</p>
|
| 10 |
+
</div>
|
| 11 |
+
<div class="col-md-3">
|
| 12 |
+
<h5>Quick Links</h5>
|
| 13 |
+
<ul class="list-unstyled">
|
| 14 |
+
<li><a href="index.php" class="text-white"><i class="fas fa-home me-1"></i> Home</a></li>
|
| 15 |
+
<li><a href="domains.php" class="text-white"><i class="fas fa-layer-group me-1"></i> Domains</a></li>
|
| 16 |
+
<li><a href="projects.php" class="text-white"><i class="fas fa-project-diagram me-1"></i> Projects</a></li>
|
| 17 |
+
<li><a href="students.php" class="text-white"><i class="fas fa-user-graduate me-1"></i> Students</a></li>
|
| 18 |
+
</ul>
|
| 19 |
+
</div>
|
| 20 |
+
<div class="col-md-3">
|
| 21 |
+
<h5>User Account</h5>
|
| 22 |
+
<ul class="list-unstyled">
|
| 23 |
+
<?php if(isset($_SESSION['user_id'])): ?>
|
| 24 |
+
<li><a href="profile.php" class="text-white"><i class="fas fa-id-card me-1"></i> My Profile</a></li>
|
| 25 |
+
<li><a href="logout.php" class="text-white"><i class="fas fa-sign-out-alt me-1"></i> Logout</a></li>
|
| 26 |
+
<?php else: ?>
|
| 27 |
+
<li><a href="login.php" class="text-white"><i class="fas fa-sign-in-alt me-1"></i> Login</a></li>
|
| 28 |
+
<li><a href="register.php" class="text-white"><i class="fas fa-user-plus me-1"></i> Register</a></li>
|
| 29 |
+
<?php endif; ?>
|
| 30 |
+
</ul>
|
| 31 |
+
</div>
|
| 32 |
+
</div>
|
| 33 |
+
<hr class="my-4">
|
| 34 |
+
<div class="row">
|
| 35 |
+
<div class="col-md-12 text-center">
|
| 36 |
+
<p class="mb-0">© <?php echo date('Y'); ?> Domain Management System. All rights reserved.</p>
|
| 37 |
+
</div>
|
| 38 |
+
</div>
|
| 39 |
+
</div>
|
| 40 |
+
</footer>
|
| 41 |
+
|
| 42 |
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
| 43 |
+
<script src="js/script.js"></script>
|
| 44 |
+
</body>
|
| 45 |
+
</html>
|
get_domain_fields.php
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection
|
| 3 |
+
require_once '../includes/db_connect.php';
|
| 4 |
+
require_once '../includes/auth_check.php';
|
| 5 |
+
|
| 6 |
+
// Ensure only faculty can access this endpoint
|
| 7 |
+
if (!isset($_SESSION['user_id']) || $_SESSION['user_type'] !== 'faculty') {
|
| 8 |
+
header('Content-Type: application/json');
|
| 9 |
+
echo json_encode(['error' => 'Unauthorized access']);
|
| 10 |
+
exit;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
// Set content type to JSON
|
| 14 |
+
header('Content-Type: application/json');
|
| 15 |
+
|
| 16 |
+
// Check if domain parameter is provided
|
| 17 |
+
if (!isset($_GET['domain']) || !is_numeric($_GET['domain'])) {
|
| 18 |
+
echo json_encode(['error' => 'Invalid domain parameter']);
|
| 19 |
+
exit;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
$domainNumber = intval($_GET['domain']);
|
| 23 |
+
$domainTable = "domain_" . $domainNumber;
|
| 24 |
+
|
| 25 |
+
// Check if table exists
|
| 26 |
+
$tableCheckQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 27 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 28 |
+
|
| 29 |
+
if (!$tableExists) {
|
| 30 |
+
echo json_encode(['error' => 'Domain table does not exist']);
|
| 31 |
+
exit;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// Get columns of the domain table
|
| 35 |
+
$columnsQuery = "SHOW COLUMNS FROM $domainTable";
|
| 36 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 37 |
+
$fields = [];
|
| 38 |
+
|
| 39 |
+
if ($columnsResult) {
|
| 40 |
+
// Process existing fields
|
| 41 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 42 |
+
$fieldName = $column['Field'];
|
| 43 |
+
|
| 44 |
+
// Skip common fields like Project_ID
|
| 45 |
+
if (in_array($fieldName, ['Project_ID', 'Domain_ID'])) {
|
| 46 |
+
continue;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// Process field type and attributes
|
| 50 |
+
$fieldType = $column['Type'];
|
| 51 |
+
$isRequired = strtoupper($column['Null']) === 'NO';
|
| 52 |
+
$defaultValue = $column['Default'];
|
| 53 |
+
|
| 54 |
+
// Determine field type for form input
|
| 55 |
+
$inputType = 'text'; // Default
|
| 56 |
+
|
| 57 |
+
if (strpos($fieldType, 'text') !== false) {
|
| 58 |
+
$inputType = 'textarea';
|
| 59 |
+
} else if (strpos($fieldType, 'enum') !== false) {
|
| 60 |
+
$inputType = 'select';
|
| 61 |
+
// Extract options from enum
|
| 62 |
+
preg_match_all("/'(.*?)'/", $fieldType, $matches);
|
| 63 |
+
$options = $matches[1] ?? [];
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
// Add field to the response
|
| 67 |
+
$fields[] = [
|
| 68 |
+
'name' => $fieldName,
|
| 69 |
+
'type' => $inputType,
|
| 70 |
+
'options' => isset($options) ? $options : null,
|
| 71 |
+
'required' => $isRequired,
|
| 72 |
+
'default' => $defaultValue
|
| 73 |
+
];
|
| 74 |
+
|
| 75 |
+
// Clear options for next field
|
| 76 |
+
unset($options);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
echo json_encode(['success' => true, 'fields' => $fields]);
|
| 80 |
+
} else {
|
| 81 |
+
echo json_encode(['error' => 'Could not retrieve domain fields']);
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
// Close connection
|
| 85 |
+
$conn->close();
|
| 86 |
+
?>
|
header.php
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Start session if not already started
|
| 3 |
+
if (session_status() === PHP_SESSION_NONE) {
|
| 4 |
+
session_start();
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
// Check if user is logged in
|
| 8 |
+
$is_logged_in = isset($_SESSION['user_id']);
|
| 9 |
+
$is_faculty = $is_logged_in && $_SESSION['user_type'] === 'faculty';
|
| 10 |
+
$is_student = $is_logged_in && $_SESSION['user_type'] === 'student';
|
| 11 |
+
|
| 12 |
+
?>
|
| 13 |
+
<!DOCTYPE html>
|
| 14 |
+
<html lang="en">
|
| 15 |
+
<head>
|
| 16 |
+
<meta charset="UTF-8">
|
| 17 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 18 |
+
<title>Domain Management System</title>
|
| 19 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 20 |
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
| 21 |
+
<link href="css/styles.css" rel="stylesheet">
|
| 22 |
+
</head>
|
| 23 |
+
<body>
|
| 24 |
+
<nav class="navbar navbar-expand-lg navbar-dark bg-dark shadow-sm mb-4">
|
| 25 |
+
<div class="container">
|
| 26 |
+
<a class="navbar-brand" href="index.php">
|
| 27 |
+
<i class="fas fa-database me-2"></i>
|
| 28 |
+
Domain Management System
|
| 29 |
+
</a>
|
| 30 |
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
| 31 |
+
<span class="navbar-toggler-icon"></span>
|
| 32 |
+
</button>
|
| 33 |
+
<div class="collapse navbar-collapse" id="navbarNav">
|
| 34 |
+
<ul class="navbar-nav me-auto">
|
| 35 |
+
<li class="nav-item">
|
| 36 |
+
<a class="nav-link" href="index.php"><i class="fas fa-home me-1"></i> Home</a>
|
| 37 |
+
</li>
|
| 38 |
+
<li class="nav-item">
|
| 39 |
+
<a class="nav-link" href="domains.php"><i class="fas fa-layer-group me-1"></i> Domains</a>
|
| 40 |
+
</li>
|
| 41 |
+
<li class="nav-item">
|
| 42 |
+
<a class="nav-link" href="projects.php"><i class="fas fa-project-diagram me-1"></i> Projects</a>
|
| 43 |
+
</li>
|
| 44 |
+
<?php if (!$is_student): // Only show Students page to faculty ?>
|
| 45 |
+
<li class="nav-item">
|
| 46 |
+
<a class="nav-link" href="students.php"><i class="fas fa-user-graduate me-1"></i> Students</a>
|
| 47 |
+
</li>
|
| 48 |
+
<?php endif; ?>
|
| 49 |
+
<?php if ($is_faculty): ?>
|
| 50 |
+
<li class="nav-item dropdown">
|
| 51 |
+
<a class="nav-link dropdown-toggle" href="#" id="projectManagementDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
| 52 |
+
<i class="fas fa-tools me-1"></i> Project Management
|
| 53 |
+
</a>
|
| 54 |
+
<ul class="dropdown-menu" aria-labelledby="projectManagementDropdown">
|
| 55 |
+
<li><a class="dropdown-item" href="project_add.php"><i class="fas fa-plus-circle me-1"></i> Add Project</a></li>
|
| 56 |
+
<li><a class="dropdown-item" href="project_manage.php"><i class="fas fa-edit me-1"></i> Manage Projects</a></li>
|
| 57 |
+
</ul>
|
| 58 |
+
</li>
|
| 59 |
+
<li class="nav-item">
|
| 60 |
+
<a class="nav-link" href="admin.php"><i class="fas fa-cogs me-1"></i> Admin Panel</a>
|
| 61 |
+
</li>
|
| 62 |
+
<?php endif; ?>
|
| 63 |
+
</ul>
|
| 64 |
+
<ul class="navbar-nav">
|
| 65 |
+
<?php if ($is_logged_in): ?>
|
| 66 |
+
<li class="nav-item dropdown">
|
| 67 |
+
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
| 68 |
+
<i class="fas fa-user-circle me-1"></i>
|
| 69 |
+
<?php echo htmlspecialchars($_SESSION['username']); ?>
|
| 70 |
+
(<?php echo ucfirst($_SESSION['user_type']); ?>)
|
| 71 |
+
</a>
|
| 72 |
+
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
| 73 |
+
<?php if ($is_student): ?>
|
| 74 |
+
<li><a class="dropdown-item" href="my_projects.php"><i class="fas fa-tasks me-1"></i> My Projects</a></li>
|
| 75 |
+
<?php endif; ?>
|
| 76 |
+
<li><a class="dropdown-item" href="profile.php"><i class="fas fa-id-card me-1"></i> My Profile</a></li>
|
| 77 |
+
<li><hr class="dropdown-divider"></li>
|
| 78 |
+
<li><a class="dropdown-item" href="logout.php"><i class="fas fa-sign-out-alt me-1"></i> Logout</a></li>
|
| 79 |
+
</ul>
|
| 80 |
+
</li>
|
| 81 |
+
<?php else: ?>
|
| 82 |
+
<li class="nav-item">
|
| 83 |
+
<a class="nav-link" href="login.php"><i class="fas fa-sign-in-alt me-1"></i> Login</a>
|
| 84 |
+
</li>
|
| 85 |
+
<?php endif; ?>
|
| 86 |
+
</ul>
|
| 87 |
+
</div>
|
| 88 |
+
</div>
|
| 89 |
+
</nav>
|
| 90 |
+
|
| 91 |
+
<div class="container mb-4">
|
| 92 |
+
<main class="container py-4">
|
index.php
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Get all domains using the utility function
|
| 8 |
+
$domainTables = getDomainTables($conn);
|
| 9 |
+
$domainCount = count($domainTables);
|
| 10 |
+
|
| 11 |
+
// Get project count using the utility function
|
| 12 |
+
$projectCount = getTotalProjectCount($conn);
|
| 13 |
+
|
| 14 |
+
// Get student information if available
|
| 15 |
+
$studentCountQuery = "SHOW TABLES LIKE 'students_info'";
|
| 16 |
+
$studentTableExists = $conn->query($studentCountQuery)->num_rows > 0;
|
| 17 |
+
|
| 18 |
+
$studentCount = "N/A";
|
| 19 |
+
if ($studentTableExists) {
|
| 20 |
+
$countStudentsQuery = "SELECT COUNT(*) as student_count FROM students_info";
|
| 21 |
+
$countStudentsResult = $conn->query($countStudentsQuery);
|
| 22 |
+
if ($countStudentsResult && $countStudentsResult->num_rows > 0) {
|
| 23 |
+
$studentCount = $countStudentsResult->fetch_assoc()['student_count'];
|
| 24 |
+
}
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
// Get recent projects from all domains
|
| 28 |
+
$recentProjects = [];
|
| 29 |
+
foreach ($domainTables as $tableName) {
|
| 30 |
+
$domainNumber = str_replace('domain_', '', $tableName);
|
| 31 |
+
|
| 32 |
+
// Get the correct project name field
|
| 33 |
+
$projectNameField = getProjectNameField($conn, $tableName);
|
| 34 |
+
|
| 35 |
+
$recentProjectsQuery = "SELECT *, '$domainNumber' as domain_number FROM $tableName ORDER BY Project_ID DESC LIMIT 3";
|
| 36 |
+
$recentProjectsResult = $conn->query($recentProjectsQuery);
|
| 37 |
+
|
| 38 |
+
if ($recentProjectsResult && $recentProjectsResult->num_rows > 0) {
|
| 39 |
+
while ($project = $recentProjectsResult->fetch_assoc()) {
|
| 40 |
+
$project['project_name_field'] = $projectNameField;
|
| 41 |
+
$recentProjects[] = $project;
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
// Sort recent projects by ID in descending order and limit to 5
|
| 47 |
+
usort($recentProjects, function($a, $b) {
|
| 48 |
+
return intval($b['Project_ID']) - intval($a['Project_ID']);
|
| 49 |
+
});
|
| 50 |
+
$recentProjects = array_slice($recentProjects, 0, 5);
|
| 51 |
+
|
| 52 |
+
// Get domain descriptions
|
| 53 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 54 |
+
|
| 55 |
+
// Include header
|
| 56 |
+
include 'includes/header.php';
|
| 57 |
+
?>
|
| 58 |
+
|
| 59 |
+
<div class="row mb-4">
|
| 60 |
+
<div class="col-md-12">
|
| 61 |
+
<div class="card bg-primary text-white">
|
| 62 |
+
<div class="card-body">
|
| 63 |
+
<h2 class="card-title">Welcome to the Domain Management System!</h2>
|
| 64 |
+
<p class="card-text">This system provides access to projects, domains, and student information from our database.</p>
|
| 65 |
+
<?php if (isset($_SESSION['user_type'])): ?>
|
| 66 |
+
<p class="card-text">Logged in as: <?php echo $_SESSION['username']; ?> (<?php echo ucfirst($_SESSION['user_type']); ?>)</p>
|
| 67 |
+
<?php endif; ?>
|
| 68 |
+
</div>
|
| 69 |
+
</div>
|
| 70 |
+
</div>
|
| 71 |
+
</div>
|
| 72 |
+
|
| 73 |
+
<div class="row mb-4">
|
| 74 |
+
<div class="col-md-4">
|
| 75 |
+
<div class="card text-center mb-3 shadow-sm">
|
| 76 |
+
<div class="card-body">
|
| 77 |
+
<i class="fas fa-layer-group fa-3x mb-3 text-primary"></i>
|
| 78 |
+
<h5 class="card-title">Domains</h5>
|
| 79 |
+
<p class="card-text display-4"><?php echo $domainCount; ?></p>
|
| 80 |
+
<a href="domains.php" class="btn btn-primary">View All Domains</a>
|
| 81 |
+
</div>
|
| 82 |
+
</div>
|
| 83 |
+
</div>
|
| 84 |
+
<div class="col-md-4">
|
| 85 |
+
<div class="card text-center mb-3 shadow-sm">
|
| 86 |
+
<div class="card-body">
|
| 87 |
+
<i class="fas fa-project-diagram fa-3x mb-3 text-primary"></i>
|
| 88 |
+
<h5 class="card-title">Projects</h5>
|
| 89 |
+
<p class="card-text display-4"><?php echo $projectCount; ?></p>
|
| 90 |
+
<a href="projects.php" class="btn btn-primary">View All Projects</a>
|
| 91 |
+
</div>
|
| 92 |
+
</div>
|
| 93 |
+
</div>
|
| 94 |
+
<div class="col-md-4">
|
| 95 |
+
<div class="card text-center mb-3 shadow-sm">
|
| 96 |
+
<div class="card-body">
|
| 97 |
+
<i class="fas fa-user-graduate fa-3x mb-3 text-primary"></i>
|
| 98 |
+
<h5 class="card-title">Students</h5>
|
| 99 |
+
<p class="card-text display-4"><?php echo $studentCount; ?></p>
|
| 100 |
+
<a href="students.php" class="btn btn-primary">View All Students</a>
|
| 101 |
+
</div>
|
| 102 |
+
</div>
|
| 103 |
+
</div>
|
| 104 |
+
</div>
|
| 105 |
+
|
| 106 |
+
<div class="row">
|
| 107 |
+
<div class="col-md-12">
|
| 108 |
+
<div class="card shadow-sm">
|
| 109 |
+
<div class="card-header bg-dark text-white">
|
| 110 |
+
<h5 class="mb-0"><i class="fas fa-clock mr-2"></i> Recent Projects</h5>
|
| 111 |
+
</div>
|
| 112 |
+
<div class="card-body">
|
| 113 |
+
<?php if (!empty($recentProjects)): ?>
|
| 114 |
+
<div class="table-responsive">
|
| 115 |
+
<table class="table table-striped table-hover">
|
| 116 |
+
<thead class="thead-light">
|
| 117 |
+
<tr>
|
| 118 |
+
<th>Project ID</th>
|
| 119 |
+
<th>Project Name</th>
|
| 120 |
+
<th>Type</th>
|
| 121 |
+
<th>Domain</th>
|
| 122 |
+
<th>Action</th>
|
| 123 |
+
</tr>
|
| 124 |
+
</thead>
|
| 125 |
+
<tbody>
|
| 126 |
+
<?php foreach ($recentProjects as $project):
|
| 127 |
+
// Get project name using the correct field
|
| 128 |
+
$projectNameField = $project['project_name_field'];
|
| 129 |
+
$projectName = $project[$projectNameField];
|
| 130 |
+
$domainNumber = $project['domain_number'];
|
| 131 |
+
$domainDesc = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : 'Domain ' . $domainNumber;
|
| 132 |
+
?>
|
| 133 |
+
<tr>
|
| 134 |
+
<td><?php echo $project['Project_ID']; ?></td>
|
| 135 |
+
<td><?php echo $projectName; ?></td>
|
| 136 |
+
<td><span class="badge <?php echo $project['H/S'] === 'Hardware' ? 'bg-danger' : 'bg-success'; ?>"><?php echo $project['H/S']; ?></span></td>
|
| 137 |
+
<td>Domain <?php echo $domainNumber; ?>: <?php echo $domainDesc; ?></td>
|
| 138 |
+
<td>
|
| 139 |
+
<a href="project_details.php?domain=<?php echo $domainNumber; ?>&id=<?php echo $project['Project_ID']; ?>" class="btn btn-sm btn-info">
|
| 140 |
+
<i class="fas fa-eye"></i> View Details
|
| 141 |
+
</a>
|
| 142 |
+
</td>
|
| 143 |
+
</tr>
|
| 144 |
+
<?php endforeach; ?>
|
| 145 |
+
</tbody>
|
| 146 |
+
</table>
|
| 147 |
+
</div>
|
| 148 |
+
<?php else: ?>
|
| 149 |
+
<div class="alert alert-info">
|
| 150 |
+
<i class="fas fa-info-circle"></i> No projects found.
|
| 151 |
+
</div>
|
| 152 |
+
<?php endif; ?>
|
| 153 |
+
</div>
|
| 154 |
+
</div>
|
| 155 |
+
</div>
|
| 156 |
+
</div>
|
| 157 |
+
|
| 158 |
+
<?php
|
| 159 |
+
// Include footer
|
| 160 |
+
include 'includes/footer.php';
|
| 161 |
+
|
| 162 |
+
// Close connection
|
| 163 |
+
$conn->close();
|
| 164 |
+
?>
|
login.php
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
|
| 5 |
+
// Start session if not already started
|
| 6 |
+
if (session_status() === PHP_SESSION_NONE) {
|
| 7 |
+
session_start();
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
// Redirect if already logged in
|
| 11 |
+
if (isset($_SESSION['user_id'])) {
|
| 12 |
+
header("Location: index.php");
|
| 13 |
+
exit;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
// Initialize variables
|
| 17 |
+
$error = '';
|
| 18 |
+
$username = '';
|
| 19 |
+
|
| 20 |
+
// Create users table if it doesn't exist
|
| 21 |
+
$createUsersTableQuery = "CREATE TABLE IF NOT EXISTS users (
|
| 22 |
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
| 23 |
+
username VARCHAR(50) NOT NULL UNIQUE,
|
| 24 |
+
email VARCHAR(100),
|
| 25 |
+
password VARCHAR(255) NOT NULL,
|
| 26 |
+
user_type ENUM('student', 'faculty') NOT NULL,
|
| 27 |
+
status ENUM('active', 'inactive') DEFAULT 'active',
|
| 28 |
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 29 |
+
last_login TIMESTAMP NULL DEFAULT NULL
|
| 30 |
+
)";
|
| 31 |
+
$conn->query($createUsersTableQuery);
|
| 32 |
+
|
| 33 |
+
// Check if admin user exists
|
| 34 |
+
$adminCheckQuery = "SELECT * FROM users WHERE username = 'admin' AND user_type = 'faculty'";
|
| 35 |
+
$adminResult = $conn->query($adminCheckQuery);
|
| 36 |
+
|
| 37 |
+
if ($adminResult && $adminResult->num_rows === 0) {
|
| 38 |
+
// Create default admin user
|
| 39 |
+
$adminPassword = password_hash('admin', PASSWORD_DEFAULT);
|
| 40 |
+
$createAdminQuery = "INSERT INTO users (username, email, password, user_type) VALUES ('admin', 'admin@example.com', '$adminPassword', 'faculty')";
|
| 41 |
+
$conn->query($createAdminQuery);
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// Process login form
|
| 45 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 46 |
+
$username = trim($_POST['username']);
|
| 47 |
+
$password = $_POST['password'];
|
| 48 |
+
$userType = $_POST['user_type'];
|
| 49 |
+
|
| 50 |
+
// Basic validation
|
| 51 |
+
if (empty($username) || empty($password) || empty($userType)) {
|
| 52 |
+
$error = "Please enter both username and password and select user type.";
|
| 53 |
+
} else {
|
| 54 |
+
if ($userType === 'faculty') {
|
| 55 |
+
// Faculty login - check against users table
|
| 56 |
+
$query = "SELECT * FROM users WHERE username = ? AND user_type = 'faculty' AND status = 'active'";
|
| 57 |
+
$stmt = $conn->prepare($query);
|
| 58 |
+
$stmt->bind_param("s", $username);
|
| 59 |
+
$stmt->execute();
|
| 60 |
+
$result = $stmt->get_result();
|
| 61 |
+
|
| 62 |
+
if ($result->num_rows === 1) {
|
| 63 |
+
$user = $result->fetch_assoc();
|
| 64 |
+
|
| 65 |
+
// Verify password
|
| 66 |
+
if (password_verify($password, $user['password'])) {
|
| 67 |
+
// Set session variables
|
| 68 |
+
$_SESSION['user_id'] = $user['id'];
|
| 69 |
+
$_SESSION['username'] = $user['username'];
|
| 70 |
+
$_SESSION['user_type'] = 'faculty';
|
| 71 |
+
|
| 72 |
+
// Update last login time
|
| 73 |
+
$updateQuery = "UPDATE users SET last_login = NOW() WHERE id = ?";
|
| 74 |
+
$updateStmt = $conn->prepare($updateQuery);
|
| 75 |
+
$updateStmt->bind_param("i", $user['id']);
|
| 76 |
+
$updateStmt->execute();
|
| 77 |
+
|
| 78 |
+
// Redirect to home page
|
| 79 |
+
header("Location: index.php");
|
| 80 |
+
exit;
|
| 81 |
+
} else {
|
| 82 |
+
$error = "Invalid username or password.";
|
| 83 |
+
}
|
| 84 |
+
} else {
|
| 85 |
+
$error = "Invalid username or password.";
|
| 86 |
+
}
|
| 87 |
+
} else {
|
| 88 |
+
// Student login - check against students_info table
|
| 89 |
+
$studentCheckQuery = "SHOW TABLES LIKE 'students_info'";
|
| 90 |
+
$tableExists = $conn->query($studentCheckQuery)->num_rows > 0;
|
| 91 |
+
|
| 92 |
+
if ($tableExists) {
|
| 93 |
+
// Get student data structure
|
| 94 |
+
$columnsQuery = "SHOW COLUMNS FROM students_info";
|
| 95 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 96 |
+
$studentIdField = null;
|
| 97 |
+
|
| 98 |
+
// Find student ID field (assuming it's either 'student_id', 'Student_ID', or similar)
|
| 99 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 100 |
+
if (preg_match('/(student|stud|roll)[\s_-]?(id|number|no)/i', $column['Field'])) {
|
| 101 |
+
$studentIdField = $column['Field'];
|
| 102 |
+
break;
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
if ($studentIdField) {
|
| 107 |
+
$query = "SELECT * FROM students_info WHERE $studentIdField = ?";
|
| 108 |
+
$stmt = $conn->prepare($query);
|
| 109 |
+
$stmt->bind_param("s", $username);
|
| 110 |
+
$stmt->execute();
|
| 111 |
+
$result = $stmt->get_result();
|
| 112 |
+
|
| 113 |
+
if ($result->num_rows === 1) {
|
| 114 |
+
$student = $result->fetch_assoc();
|
| 115 |
+
|
| 116 |
+
// For students, password should be same as student ID for simplicity
|
| 117 |
+
if ($password === $username) {
|
| 118 |
+
// Create or update user record for this student
|
| 119 |
+
$userCheckQuery = "SELECT * FROM users WHERE username = ? AND user_type = 'student'";
|
| 120 |
+
$userCheckStmt = $conn->prepare($userCheckQuery);
|
| 121 |
+
$userCheckStmt->bind_param("s", $username);
|
| 122 |
+
$userCheckStmt->execute();
|
| 123 |
+
$userResult = $userCheckStmt->get_result();
|
| 124 |
+
|
| 125 |
+
if ($userResult->num_rows === 0) {
|
| 126 |
+
// Create new user record
|
| 127 |
+
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
| 128 |
+
$createUserQuery = "INSERT INTO users (username, password, user_type) VALUES (?, ?, 'student')";
|
| 129 |
+
$createUserStmt = $conn->prepare($createUserQuery);
|
| 130 |
+
$createUserStmt->bind_param("ss", $username, $hashedPassword);
|
| 131 |
+
$createUserStmt->execute();
|
| 132 |
+
$userId = $conn->insert_id;
|
| 133 |
+
} else {
|
| 134 |
+
$user = $userResult->fetch_assoc();
|
| 135 |
+
$userId = $user['id'];
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
// Set session variables
|
| 139 |
+
$_SESSION['user_id'] = $userId;
|
| 140 |
+
$_SESSION['username'] = $username;
|
| 141 |
+
$_SESSION['user_type'] = 'student';
|
| 142 |
+
$_SESSION['student_id'] = $student[$studentIdField];
|
| 143 |
+
|
| 144 |
+
// Update last login time
|
| 145 |
+
$updateQuery = "UPDATE users SET last_login = NOW() WHERE id = ?";
|
| 146 |
+
$updateStmt = $conn->prepare($updateQuery);
|
| 147 |
+
$updateStmt->bind_param("i", $userId);
|
| 148 |
+
$updateStmt->execute();
|
| 149 |
+
|
| 150 |
+
// Redirect to home page
|
| 151 |
+
header("Location: index.php");
|
| 152 |
+
exit;
|
| 153 |
+
} else {
|
| 154 |
+
$error = "Invalid password. Students should use their student ID as password.";
|
| 155 |
+
}
|
| 156 |
+
} else {
|
| 157 |
+
$error = "Student ID not found in our records.";
|
| 158 |
+
}
|
| 159 |
+
} else {
|
| 160 |
+
$error = "Student ID field not found in database structure.";
|
| 161 |
+
}
|
| 162 |
+
} else {
|
| 163 |
+
$error = "Student information table not found.";
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
// Check for success message
|
| 170 |
+
$success = '';
|
| 171 |
+
if (isset($_SESSION['success_message'])) {
|
| 172 |
+
$success = $_SESSION['success_message'];
|
| 173 |
+
unset($_SESSION['success_message']);
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
// Include header
|
| 177 |
+
include 'includes/header.php';
|
| 178 |
+
?>
|
| 179 |
+
|
| 180 |
+
<div class="row mb-4 text-center">
|
| 181 |
+
<div class="col-md-12">
|
| 182 |
+
<h2><i class="fas fa-sign-in-alt me-2"></i> Login to Domain Management System</h2>
|
| 183 |
+
<p class="lead">Access the project database with your credentials</p>
|
| 184 |
+
</div>
|
| 185 |
+
</div>
|
| 186 |
+
|
| 187 |
+
<div class="row">
|
| 188 |
+
<div class="col-md-6 offset-md-3">
|
| 189 |
+
<div class="card shadow-sm">
|
| 190 |
+
<div class="card-header bg-primary text-white">
|
| 191 |
+
<h4 class="mb-0"><i class="fas fa-sign-in-alt me-2"></i> Login</h4>
|
| 192 |
+
</div>
|
| 193 |
+
<div class="card-body">
|
| 194 |
+
<?php if (!empty($error)): ?>
|
| 195 |
+
<div class="alert alert-danger">
|
| 196 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 197 |
+
</div>
|
| 198 |
+
<?php endif; ?>
|
| 199 |
+
|
| 200 |
+
<?php if (!empty($success)): ?>
|
| 201 |
+
<div class="alert alert-success">
|
| 202 |
+
<i class="fas fa-check-circle me-2"></i> <?php echo $success; ?>
|
| 203 |
+
</div>
|
| 204 |
+
<?php endif; ?>
|
| 205 |
+
|
| 206 |
+
<form method="post" action="login.php">
|
| 207 |
+
<div class="mb-3">
|
| 208 |
+
<label for="user_type" class="form-label">Login As</label>
|
| 209 |
+
<div class="input-group">
|
| 210 |
+
<span class="input-group-text"><i class="fas fa-users"></i></span>
|
| 211 |
+
<select name="user_type" id="user_type" class="form-select" required>
|
| 212 |
+
<option value="">Select User Type</option>
|
| 213 |
+
<option value="student">Student</option>
|
| 214 |
+
<option value="faculty">Faculty</option>
|
| 215 |
+
</select>
|
| 216 |
+
</div>
|
| 217 |
+
</div>
|
| 218 |
+
|
| 219 |
+
<div class="mb-3">
|
| 220 |
+
<label for="username" class="form-label" id="username_label">Username</label>
|
| 221 |
+
<div class="input-group">
|
| 222 |
+
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
| 223 |
+
<input type="text" class="form-control" id="username" name="username" value="<?php echo htmlspecialchars($username); ?>" required>
|
| 224 |
+
</div>
|
| 225 |
+
<small class="form-text text-muted student-info d-none">Enter your Student ID</small>
|
| 226 |
+
<small class="form-text text-muted faculty-info d-none">Faculty username (admin)</small>
|
| 227 |
+
</div>
|
| 228 |
+
|
| 229 |
+
<div class="mb-4">
|
| 230 |
+
<label for="password" class="form-label">Password</label>
|
| 231 |
+
<div class="input-group">
|
| 232 |
+
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
| 233 |
+
<input type="password" class="form-control" id="password" name="password" required>
|
| 234 |
+
<button class="btn btn-outline-secondary toggle-password" type="button" data-target="#password">
|
| 235 |
+
<i class="fas fa-eye"></i>
|
| 236 |
+
</button>
|
| 237 |
+
</div>
|
| 238 |
+
<small class="form-text text-muted student-info d-none">Use your Student ID as password</small>
|
| 239 |
+
<small class="form-text text-muted faculty-info d-none">Default faculty password is 'admin'</small>
|
| 240 |
+
</div>
|
| 241 |
+
|
| 242 |
+
<div class="d-grid gap-2">
|
| 243 |
+
<button type="submit" class="btn btn-primary">
|
| 244 |
+
<i class="fas fa-sign-in-alt me-2"></i> Login
|
| 245 |
+
</button>
|
| 246 |
+
</div>
|
| 247 |
+
</form>
|
| 248 |
+
</div>
|
| 249 |
+
</div>
|
| 250 |
+
</div>
|
| 251 |
+
</div>
|
| 252 |
+
|
| 253 |
+
<script>
|
| 254 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 255 |
+
// Show/hide helper text based on user type selection
|
| 256 |
+
const userTypeSelect = document.getElementById('user_type');
|
| 257 |
+
const studentInfoElements = document.querySelectorAll('.student-info');
|
| 258 |
+
const facultyInfoElements = document.querySelectorAll('.faculty-info');
|
| 259 |
+
const usernameLabel = document.getElementById('username_label');
|
| 260 |
+
|
| 261 |
+
userTypeSelect.addEventListener('change', function() {
|
| 262 |
+
// Hide all helper texts first
|
| 263 |
+
studentInfoElements.forEach(el => el.classList.add('d-none'));
|
| 264 |
+
facultyInfoElements.forEach(el => el.classList.add('d-none'));
|
| 265 |
+
|
| 266 |
+
// Show appropriate helper text based on selection
|
| 267 |
+
if (this.value === 'student') {
|
| 268 |
+
studentInfoElements.forEach(el => el.classList.remove('d-none'));
|
| 269 |
+
usernameLabel.textContent = 'Student ID';
|
| 270 |
+
} else if (this.value === 'faculty') {
|
| 271 |
+
facultyInfoElements.forEach(el => el.classList.remove('d-none'));
|
| 272 |
+
usernameLabel.textContent = 'Username';
|
| 273 |
+
} else {
|
| 274 |
+
usernameLabel.textContent = 'Username';
|
| 275 |
+
}
|
| 276 |
+
});
|
| 277 |
+
});
|
| 278 |
+
</script>
|
| 279 |
+
|
| 280 |
+
<?php
|
| 281 |
+
// Include footer
|
| 282 |
+
include 'includes/footer.php';
|
| 283 |
+
|
| 284 |
+
// Close connection
|
| 285 |
+
$conn->close();
|
| 286 |
+
?>
|
logout.php
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Logout Script
|
| 4 |
+
*
|
| 5 |
+
* This script handles user logout by destroying the session
|
| 6 |
+
* and redirecting the user to the login page.
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
// Start session if not already started
|
| 10 |
+
if (session_status() === PHP_SESSION_NONE) {
|
| 11 |
+
session_start();
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
// Clear all session variables
|
| 15 |
+
$_SESSION = array();
|
| 16 |
+
|
| 17 |
+
// If it's desired to kill the session, also delete the session cookie.
|
| 18 |
+
if (ini_get("session.use_cookies")) {
|
| 19 |
+
$params = session_get_cookie_params();
|
| 20 |
+
setcookie(session_name(), '', time() - 42000,
|
| 21 |
+
$params["path"], $params["domain"],
|
| 22 |
+
$params["secure"], $params["httponly"]
|
| 23 |
+
);
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
// Destroy the session
|
| 27 |
+
session_destroy();
|
| 28 |
+
|
| 29 |
+
// Set a success message for the login page
|
| 30 |
+
session_start();
|
| 31 |
+
$_SESSION['success_message'] = "You have been successfully logged out.";
|
| 32 |
+
|
| 33 |
+
// Redirect to login page
|
| 34 |
+
header("Location: login.php");
|
| 35 |
+
exit;
|
| 36 |
+
?>
|
my_projects.php
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// This page is for students only
|
| 8 |
+
requireStudent();
|
| 9 |
+
|
| 10 |
+
// Get student ID from session
|
| 11 |
+
$studentId = $_SESSION['user_id'];
|
| 12 |
+
$error = '';
|
| 13 |
+
$studentData = null;
|
| 14 |
+
$studentProjects = [];
|
| 15 |
+
$studentName = "Student";
|
| 16 |
+
|
| 17 |
+
// Check if students_info table exists
|
| 18 |
+
$tableCheckQuery = "SHOW TABLES LIKE 'students_info'";
|
| 19 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 20 |
+
|
| 21 |
+
if ($tableExists) {
|
| 22 |
+
// Get student data structure to find the ID field
|
| 23 |
+
$columnsQuery = "SHOW COLUMNS FROM students_info";
|
| 24 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 25 |
+
$studentIdField = null;
|
| 26 |
+
$studentNameFields = [];
|
| 27 |
+
|
| 28 |
+
// Find student ID and name fields
|
| 29 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 30 |
+
if (preg_match('/(student|stud|roll)[\s_-]?(id|number|no)/i', $column['Field'])) {
|
| 31 |
+
$studentIdField = $column['Field'];
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
if (preg_match('/(student|stud)[\s_-]?(name)/i', $column['Field']) ||
|
| 35 |
+
preg_match('/(first|last|full)[\s_-]?(name)/i', $column['Field'])) {
|
| 36 |
+
$studentNameFields[] = $column['Field'];
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
if ($studentIdField) {
|
| 41 |
+
// Fetch student data
|
| 42 |
+
$studentQuery = "SELECT * FROM students_info WHERE $studentIdField = ?";
|
| 43 |
+
$stmt = $conn->prepare($studentQuery);
|
| 44 |
+
$stmt->bind_param('s', $studentId);
|
| 45 |
+
$stmt->execute();
|
| 46 |
+
$result = $stmt->get_result();
|
| 47 |
+
|
| 48 |
+
if ($result && $result->num_rows > 0) {
|
| 49 |
+
$studentData = $result->fetch_assoc();
|
| 50 |
+
|
| 51 |
+
// Set student name
|
| 52 |
+
foreach ($studentNameFields as $field) {
|
| 53 |
+
if (!empty($studentData[$field])) {
|
| 54 |
+
$studentName = $studentData[$field];
|
| 55 |
+
break;
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
// Find project field in student data
|
| 60 |
+
$projectIdField = null;
|
| 61 |
+
$domainIdField = null;
|
| 62 |
+
|
| 63 |
+
foreach ($studentData as $field => $value) {
|
| 64 |
+
if (preg_match('/(project)[\s_-]?(id)/i', $field)) {
|
| 65 |
+
$projectIdField = $field;
|
| 66 |
+
}
|
| 67 |
+
if (preg_match('/(domain)[\s_-]?(id)/i', $field)) {
|
| 68 |
+
$domainIdField = $field;
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
// If specific project field found, get project details
|
| 73 |
+
if ($projectIdField && !empty($studentData[$projectIdField])) {
|
| 74 |
+
$projectId = $studentData[$projectIdField];
|
| 75 |
+
|
| 76 |
+
// If domain field is found, use it to find the right domain table
|
| 77 |
+
if ($domainIdField && !empty($studentData[$domainIdField])) {
|
| 78 |
+
$domainId = $studentData[$domainIdField];
|
| 79 |
+
// Extract domain number if format is like 'D-1'
|
| 80 |
+
if (preg_match('/D-(\d+)/', $domainId, $matches)) {
|
| 81 |
+
$domainNumber = $matches[1];
|
| 82 |
+
$domainTable = "domain_" . $domainNumber;
|
| 83 |
+
|
| 84 |
+
// Check if table exists
|
| 85 |
+
$tableCheckQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 86 |
+
if ($conn->query($tableCheckQuery)->num_rows > 0) {
|
| 87 |
+
// Get project name field for this domain
|
| 88 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 89 |
+
|
| 90 |
+
// Fetch project details
|
| 91 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE Project_ID = ?";
|
| 92 |
+
$stmt = $conn->prepare($projectQuery);
|
| 93 |
+
$stmt->bind_param('i', $projectId);
|
| 94 |
+
$stmt->execute();
|
| 95 |
+
$projectResult = $stmt->get_result();
|
| 96 |
+
|
| 97 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 98 |
+
$project = $projectResult->fetch_assoc();
|
| 99 |
+
$project['project_name_field'] = $projectNameField;
|
| 100 |
+
$studentProjects[] = $project;
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
} else {
|
| 105 |
+
// If no domain field, search all domain tables
|
| 106 |
+
$domainTables = getDomainTables($conn);
|
| 107 |
+
|
| 108 |
+
foreach ($domainTables as $domainTable) {
|
| 109 |
+
$domainNumber = str_replace('domain_', '', $domainTable);
|
| 110 |
+
|
| 111 |
+
// Get project name field for this domain
|
| 112 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 113 |
+
|
| 114 |
+
// Check for project in this domain
|
| 115 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE Project_ID = ?";
|
| 116 |
+
$stmt = $conn->prepare($projectQuery);
|
| 117 |
+
$stmt->bind_param('i', $projectId);
|
| 118 |
+
$stmt->execute();
|
| 119 |
+
$projectResult = $stmt->get_result();
|
| 120 |
+
|
| 121 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 122 |
+
$project = $projectResult->fetch_assoc();
|
| 123 |
+
$project['project_name_field'] = $projectNameField;
|
| 124 |
+
$studentProjects[] = $project;
|
| 125 |
+
break; // Found the project, no need to search other tables
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
}
|
| 129 |
+
} else {
|
| 130 |
+
// If no specific project field or project ID is empty,
|
| 131 |
+
// try to find projects by searching for the student ID in all domain tables
|
| 132 |
+
$domainTables = getDomainTables($conn);
|
| 133 |
+
|
| 134 |
+
foreach ($domainTables as $domainTable) {
|
| 135 |
+
$domainNumber = str_replace('domain_', '', $domainTable);
|
| 136 |
+
|
| 137 |
+
// Get columns of the domain table
|
| 138 |
+
$columnsQuery = "SHOW COLUMNS FROM $domainTable";
|
| 139 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 140 |
+
$studentColumns = [];
|
| 141 |
+
|
| 142 |
+
// Find columns that might contain student IDs
|
| 143 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 144 |
+
if (preg_match('/(student|stud|member)[\s_-]?(id|ids|no|number)/i', $column['Field'])) {
|
| 145 |
+
$studentColumns[] = $column['Field'];
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
// Get project name field for this domain
|
| 150 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 151 |
+
|
| 152 |
+
// Check each potential student column
|
| 153 |
+
foreach ($studentColumns as $studentColumn) {
|
| 154 |
+
// Try exact match
|
| 155 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE $studentColumn = ?";
|
| 156 |
+
$stmt = $conn->prepare($projectQuery);
|
| 157 |
+
$stmt->bind_param('s', $studentId);
|
| 158 |
+
$stmt->execute();
|
| 159 |
+
$projectResult = $stmt->get_result();
|
| 160 |
+
|
| 161 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 162 |
+
while ($project = $projectResult->fetch_assoc()) {
|
| 163 |
+
$project['project_name_field'] = $projectNameField;
|
| 164 |
+
$studentProjects[] = $project;
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
// Try LIKE match (if the column might contain multiple IDs)
|
| 169 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE $studentColumn LIKE ?";
|
| 170 |
+
$likeParam = "%$studentId%";
|
| 171 |
+
$stmt = $conn->prepare($projectQuery);
|
| 172 |
+
$stmt->bind_param('s', $likeParam);
|
| 173 |
+
$stmt->execute();
|
| 174 |
+
$projectResult = $stmt->get_result();
|
| 175 |
+
|
| 176 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 177 |
+
while ($project = $projectResult->fetch_assoc()) {
|
| 178 |
+
// Check if this project is already added
|
| 179 |
+
$duplicate = false;
|
| 180 |
+
foreach ($studentProjects as $existingProject) {
|
| 181 |
+
if ($existingProject['Project_ID'] == $project['Project_ID'] &&
|
| 182 |
+
$existingProject['domain_number'] == $project['domain_number']) {
|
| 183 |
+
$duplicate = true;
|
| 184 |
+
break;
|
| 185 |
+
}
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
if (!$duplicate) {
|
| 189 |
+
$project['project_name_field'] = $projectNameField;
|
| 190 |
+
$studentProjects[] = $project;
|
| 191 |
+
}
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
} else {
|
| 198 |
+
$error = "Your student record was not found in the database. Please contact your administrator.";
|
| 199 |
+
}
|
| 200 |
+
} else {
|
| 201 |
+
$error = "Could not determine student ID field in the database.";
|
| 202 |
+
}
|
| 203 |
+
} else {
|
| 204 |
+
$error = "Student information table not found in the database.";
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
// Get domain descriptions for displaying domain names
|
| 208 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 209 |
+
|
| 210 |
+
// Include header
|
| 211 |
+
include 'includes/header.php';
|
| 212 |
+
?>
|
| 213 |
+
|
| 214 |
+
<div class="row mb-4">
|
| 215 |
+
<div class="col-md-12">
|
| 216 |
+
<nav aria-label="breadcrumb">
|
| 217 |
+
<ol class="breadcrumb">
|
| 218 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 219 |
+
<li class="breadcrumb-item active">My Projects</li>
|
| 220 |
+
</ol>
|
| 221 |
+
</nav>
|
| 222 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 223 |
+
<h2><i class="fas fa-project-diagram me-2"></i> My Projects</h2>
|
| 224 |
+
</div>
|
| 225 |
+
<p class="lead">View all projects assigned to you</p>
|
| 226 |
+
</div>
|
| 227 |
+
</div>
|
| 228 |
+
|
| 229 |
+
<?php if (!empty($error)): ?>
|
| 230 |
+
<div class="alert alert-danger">
|
| 231 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 232 |
+
</div>
|
| 233 |
+
<?php endif; ?>
|
| 234 |
+
|
| 235 |
+
<div class="row">
|
| 236 |
+
<div class="col-md-12">
|
| 237 |
+
<div class="card shadow-sm">
|
| 238 |
+
<div class="card-header bg-primary text-white">
|
| 239 |
+
<h5 class="mb-0"><i class="fas fa-list me-2"></i> Project List</h5>
|
| 240 |
+
</div>
|
| 241 |
+
<div class="card-body">
|
| 242 |
+
<?php if (count($studentProjects) > 0): ?>
|
| 243 |
+
<div class="table-responsive">
|
| 244 |
+
<table class="table table-striped table-hover">
|
| 245 |
+
<thead class="table-light">
|
| 246 |
+
<tr>
|
| 247 |
+
<th>Project ID</th>
|
| 248 |
+
<th>Project Name</th>
|
| 249 |
+
<th>Type</th>
|
| 250 |
+
<th>Domain</th>
|
| 251 |
+
<th>Actions</th>
|
| 252 |
+
</tr>
|
| 253 |
+
</thead>
|
| 254 |
+
<tbody>
|
| 255 |
+
<?php foreach ($studentProjects as $project):
|
| 256 |
+
$domainNumber = $project['domain_number'];
|
| 257 |
+
$domainDesc = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : 'Domain ' . $domainNumber;
|
| 258 |
+
$projectName = isset($project[$project['project_name_field']]) ? $project[$project['project_name_field']] : 'Project ' . $project['Project_ID'];
|
| 259 |
+
?>
|
| 260 |
+
<tr>
|
| 261 |
+
<td><?php echo htmlspecialchars($project['Project_ID']); ?></td>
|
| 262 |
+
<td><?php echo htmlspecialchars($projectName); ?></td>
|
| 263 |
+
<td>
|
| 264 |
+
<?php if (isset($project['H/S'])): ?>
|
| 265 |
+
<span class="badge bg-<?php echo strtolower($project['H/S']) === 'h' ? 'warning' : 'info'; ?>">
|
| 266 |
+
<?php echo strtolower($project['H/S']) === 'h' ? 'Hardware' : 'Software'; ?>
|
| 267 |
+
</span>
|
| 268 |
+
<?php else: ?>
|
| 269 |
+
<span class="badge bg-secondary">Not specified</span>
|
| 270 |
+
<?php endif; ?>
|
| 271 |
+
</td>
|
| 272 |
+
<td>Domain <?php echo htmlspecialchars($domainNumber); ?>: <?php echo htmlspecialchars($domainDesc); ?></td>
|
| 273 |
+
<td>
|
| 274 |
+
<a href="project_details.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-sm btn-info">
|
| 275 |
+
<i class="fas fa-info-circle"></i> Details
|
| 276 |
+
</a>
|
| 277 |
+
</td>
|
| 278 |
+
</tr>
|
| 279 |
+
<?php endforeach; ?>
|
| 280 |
+
</tbody>
|
| 281 |
+
</table>
|
| 282 |
+
</div>
|
| 283 |
+
<?php else: ?>
|
| 284 |
+
<div class="alert alert-info">
|
| 285 |
+
<i class="fas fa-info-circle me-2"></i> No projects are currently assigned to you. If you believe this is an error, please contact your faculty advisor.
|
| 286 |
+
</div>
|
| 287 |
+
<?php endif; ?>
|
| 288 |
+
</div>
|
| 289 |
+
</div>
|
| 290 |
+
</div>
|
| 291 |
+
</div>
|
| 292 |
+
|
| 293 |
+
<?php
|
| 294 |
+
// Include footer
|
| 295 |
+
include 'includes/footer.php';
|
| 296 |
+
|
| 297 |
+
// Close connection
|
| 298 |
+
$conn->close();
|
| 299 |
+
?>
|
profile.php
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication check
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/auth_check.php';
|
| 5 |
+
|
| 6 |
+
// Redirect to login if not logged in
|
| 7 |
+
requireLogin();
|
| 8 |
+
|
| 9 |
+
$error = '';
|
| 10 |
+
$success = '';
|
| 11 |
+
$user = null;
|
| 12 |
+
|
| 13 |
+
// Get user information
|
| 14 |
+
$user_id = $_SESSION['user_id'];
|
| 15 |
+
$query = "SELECT * FROM users WHERE id = ?";
|
| 16 |
+
$stmt = $conn->prepare($query);
|
| 17 |
+
$stmt->bind_param("i", $user_id);
|
| 18 |
+
$stmt->execute();
|
| 19 |
+
$result = $stmt->get_result();
|
| 20 |
+
|
| 21 |
+
if ($result->num_rows === 1) {
|
| 22 |
+
$user = $result->fetch_assoc();
|
| 23 |
+
} else {
|
| 24 |
+
$error = "User not found.";
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
// Process profile update form
|
| 28 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_profile'])) {
|
| 29 |
+
$email = $conn->real_escape_string(trim($_POST['email']));
|
| 30 |
+
|
| 31 |
+
// Validate email
|
| 32 |
+
if (empty($email)) {
|
| 33 |
+
$error = "Email is required.";
|
| 34 |
+
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
| 35 |
+
$error = "Please enter a valid email address.";
|
| 36 |
+
} else {
|
| 37 |
+
// Check if email is already used by another user
|
| 38 |
+
$check_query = "SELECT id FROM users WHERE email = ? AND id != ?";
|
| 39 |
+
$check_stmt = $conn->prepare($check_query);
|
| 40 |
+
$check_stmt->bind_param("si", $email, $user_id);
|
| 41 |
+
$check_stmt->execute();
|
| 42 |
+
$check_result = $check_stmt->get_result();
|
| 43 |
+
|
| 44 |
+
if ($check_result->num_rows > 0) {
|
| 45 |
+
$error = "Email is already in use by another account.";
|
| 46 |
+
} else {
|
| 47 |
+
// Update user profile
|
| 48 |
+
$update_query = "UPDATE users SET email = ? WHERE id = ?";
|
| 49 |
+
$update_stmt = $conn->prepare($update_query);
|
| 50 |
+
$update_stmt->bind_param("si", $email, $user_id);
|
| 51 |
+
|
| 52 |
+
if ($update_stmt->execute()) {
|
| 53 |
+
$_SESSION['email'] = $email;
|
| 54 |
+
$success = "Profile updated successfully.";
|
| 55 |
+
|
| 56 |
+
// Refresh user data
|
| 57 |
+
$stmt->execute();
|
| 58 |
+
$result = $stmt->get_result();
|
| 59 |
+
$user = $result->fetch_assoc();
|
| 60 |
+
} else {
|
| 61 |
+
$error = "Failed to update profile: " . $conn->error;
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// Process password change form
|
| 68 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['change_password'])) {
|
| 69 |
+
$current_password = trim($_POST['current_password']);
|
| 70 |
+
$new_password = trim($_POST['new_password']);
|
| 71 |
+
$confirm_password = trim($_POST['confirm_password']);
|
| 72 |
+
|
| 73 |
+
// Validate inputs
|
| 74 |
+
if (empty($current_password) || empty($new_password) || empty($confirm_password)) {
|
| 75 |
+
$error = "All password fields are required.";
|
| 76 |
+
} elseif (strlen($new_password) < 6) {
|
| 77 |
+
$error = "New password must be at least 6 characters long.";
|
| 78 |
+
} elseif ($new_password !== $confirm_password) {
|
| 79 |
+
$error = "New passwords do not match.";
|
| 80 |
+
} elseif (!password_verify($current_password, $user['password'])) {
|
| 81 |
+
$error = "Current password is incorrect.";
|
| 82 |
+
} else {
|
| 83 |
+
// Update password
|
| 84 |
+
$hashed_password = password_hash($new_password, PASSWORD_DEFAULT);
|
| 85 |
+
$update_query = "UPDATE users SET password = ? WHERE id = ?";
|
| 86 |
+
$update_stmt = $conn->prepare($update_query);
|
| 87 |
+
$update_stmt->bind_param("si", $hashed_password, $user_id);
|
| 88 |
+
|
| 89 |
+
if ($update_stmt->execute()) {
|
| 90 |
+
$success = "Password changed successfully.";
|
| 91 |
+
} else {
|
| 92 |
+
$error = "Failed to change password: " . $conn->error;
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
// Include header
|
| 98 |
+
include 'includes/header.php';
|
| 99 |
+
?>
|
| 100 |
+
|
| 101 |
+
<div class="row mb-4">
|
| 102 |
+
<div class="col-md-12">
|
| 103 |
+
<nav aria-label="breadcrumb">
|
| 104 |
+
<ol class="breadcrumb">
|
| 105 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 106 |
+
<li class="breadcrumb-item active">My Profile</li>
|
| 107 |
+
</ol>
|
| 108 |
+
</nav>
|
| 109 |
+
<h2><i class="fas fa-id-card me-2"></i> My Profile</h2>
|
| 110 |
+
<p class="lead">Manage your account settings and password</p>
|
| 111 |
+
</div>
|
| 112 |
+
</div>
|
| 113 |
+
|
| 114 |
+
<?php if (!empty($error)): ?>
|
| 115 |
+
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
| 116 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 117 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 118 |
+
</div>
|
| 119 |
+
<?php endif; ?>
|
| 120 |
+
|
| 121 |
+
<?php if (!empty($success)): ?>
|
| 122 |
+
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
| 123 |
+
<i class="fas fa-check-circle me-2"></i> <?php echo $success; ?>
|
| 124 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 125 |
+
</div>
|
| 126 |
+
<?php endif; ?>
|
| 127 |
+
|
| 128 |
+
<div class="row">
|
| 129 |
+
<div class="col-md-4 mb-4">
|
| 130 |
+
<div class="card shadow-sm">
|
| 131 |
+
<div class="card-header bg-primary text-white">
|
| 132 |
+
<h5 class="mb-0"><i class="fas fa-user me-2"></i> Account Information</h5>
|
| 133 |
+
</div>
|
| 134 |
+
<div class="card-body">
|
| 135 |
+
<div class="text-center mb-4">
|
| 136 |
+
<div class="avatar-circle mb-3">
|
| 137 |
+
<span class="avatar-text"><?php echo strtoupper(substr($user['username'], 0, 1)); ?></span>
|
| 138 |
+
</div>
|
| 139 |
+
<h5><?php echo htmlspecialchars($user['username']); ?></h5>
|
| 140 |
+
<span class="badge <?php echo $user['user_type'] === 'faculty' ? 'bg-danger' : 'bg-success'; ?> mb-2">
|
| 141 |
+
<?php echo ucfirst($user['user_type']); ?>
|
| 142 |
+
</span>
|
| 143 |
+
</div>
|
| 144 |
+
<ul class="list-group list-group-flush">
|
| 145 |
+
<li class="list-group-item">
|
| 146 |
+
<strong><i class="fas fa-envelope me-2"></i> Email:</strong>
|
| 147 |
+
<span class="float-end"><?php echo htmlspecialchars($user['email']); ?></span>
|
| 148 |
+
</li>
|
| 149 |
+
<li class="list-group-item">
|
| 150 |
+
<strong><i class="fas fa-clock me-2"></i> Joined:</strong>
|
| 151 |
+
<span class="float-end"><?php echo date('M d, Y', strtotime($user['created_at'])); ?></span>
|
| 152 |
+
</li>
|
| 153 |
+
<li class="list-group-item">
|
| 154 |
+
<strong><i class="fas fa-sign-in-alt me-2"></i> Last Login:</strong>
|
| 155 |
+
<span class="float-end">
|
| 156 |
+
<?php echo $user['last_login'] ? date('M d, Y H:i', strtotime($user['last_login'])) : 'Never'; ?>
|
| 157 |
+
</span>
|
| 158 |
+
</li>
|
| 159 |
+
<li class="list-group-item">
|
| 160 |
+
<strong><i class="fas fa-toggle-on me-2"></i> Status:</strong>
|
| 161 |
+
<span class="float-end">
|
| 162 |
+
<span class="badge <?php echo $user['status'] === 'active' ? 'bg-success' : 'bg-secondary'; ?>">
|
| 163 |
+
<?php echo ucfirst($user['status']); ?>
|
| 164 |
+
</span>
|
| 165 |
+
</span>
|
| 166 |
+
</li>
|
| 167 |
+
</ul>
|
| 168 |
+
</div>
|
| 169 |
+
</div>
|
| 170 |
+
</div>
|
| 171 |
+
|
| 172 |
+
<div class="col-md-8">
|
| 173 |
+
<div class="card shadow-sm mb-4">
|
| 174 |
+
<div class="card-header bg-primary text-white">
|
| 175 |
+
<h5 class="mb-0"><i class="fas fa-edit me-2"></i> Edit Profile</h5>
|
| 176 |
+
</div>
|
| 177 |
+
<div class="card-body">
|
| 178 |
+
<form method="POST" action="profile.php" class="needs-validation" novalidate>
|
| 179 |
+
<div class="mb-3">
|
| 180 |
+
<label for="username" class="form-label">Username</label>
|
| 181 |
+
<input type="text" class="form-control" id="username" value="<?php echo htmlspecialchars($user['username']); ?>" readonly>
|
| 182 |
+
<div class="form-text">Username cannot be changed.</div>
|
| 183 |
+
</div>
|
| 184 |
+
<div class="mb-3">
|
| 185 |
+
<label for="email" class="form-label">Email Address</label>
|
| 186 |
+
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($user['email']); ?>" required>
|
| 187 |
+
<div class="invalid-feedback">
|
| 188 |
+
Please enter a valid email address.
|
| 189 |
+
</div>
|
| 190 |
+
</div>
|
| 191 |
+
<div class="mb-3">
|
| 192 |
+
<label for="user_type" class="form-label">Account Type</label>
|
| 193 |
+
<input type="text" class="form-control" id="user_type" value="<?php echo ucfirst($user['user_type']); ?>" readonly>
|
| 194 |
+
<div class="form-text">Account type cannot be changed.</div>
|
| 195 |
+
</div>
|
| 196 |
+
<button type="submit" name="update_profile" class="btn btn-primary">
|
| 197 |
+
<i class="fas fa-save me-2"></i> Update Profile
|
| 198 |
+
</button>
|
| 199 |
+
</form>
|
| 200 |
+
</div>
|
| 201 |
+
</div>
|
| 202 |
+
|
| 203 |
+
<div class="card shadow-sm">
|
| 204 |
+
<div class="card-header bg-primary text-white">
|
| 205 |
+
<h5 class="mb-0"><i class="fas fa-key me-2"></i> Change Password</h5>
|
| 206 |
+
</div>
|
| 207 |
+
<div class="card-body">
|
| 208 |
+
<form method="POST" action="profile.php" class="needs-validation" novalidate>
|
| 209 |
+
<div class="mb-3">
|
| 210 |
+
<label for="current_password" class="form-label">Current Password</label>
|
| 211 |
+
<div class="input-group">
|
| 212 |
+
<input type="password" class="form-control" id="current_password" name="current_password" required>
|
| 213 |
+
<button class="btn btn-outline-secondary toggle-password" type="button" data-target="#current_password">
|
| 214 |
+
<i class="fas fa-eye"></i>
|
| 215 |
+
</button>
|
| 216 |
+
</div>
|
| 217 |
+
<div class="invalid-feedback">
|
| 218 |
+
Please enter your current password.
|
| 219 |
+
</div>
|
| 220 |
+
</div>
|
| 221 |
+
<div class="mb-3">
|
| 222 |
+
<label for="new_password" class="form-label">New Password</label>
|
| 223 |
+
<div class="input-group">
|
| 224 |
+
<input type="password" class="form-control" id="new_password" name="new_password" required minlength="6">
|
| 225 |
+
<button class="btn btn-outline-secondary toggle-password" type="button" data-target="#new_password">
|
| 226 |
+
<i class="fas fa-eye"></i>
|
| 227 |
+
</button>
|
| 228 |
+
</div>
|
| 229 |
+
<div class="form-text">Password must be at least 6 characters long.</div>
|
| 230 |
+
<div class="invalid-feedback">
|
| 231 |
+
Please enter a new password (minimum 6 characters).
|
| 232 |
+
</div>
|
| 233 |
+
</div>
|
| 234 |
+
<div class="mb-3">
|
| 235 |
+
<label for="confirm_password" class="form-label">Confirm New Password</label>
|
| 236 |
+
<div class="input-group">
|
| 237 |
+
<input type="password" class="form-control" id="confirm_password" name="confirm_password" required>
|
| 238 |
+
<button class="btn btn-outline-secondary toggle-password" type="button" data-target="#confirm_password">
|
| 239 |
+
<i class="fas fa-eye"></i>
|
| 240 |
+
</button>
|
| 241 |
+
</div>
|
| 242 |
+
<div class="invalid-feedback">
|
| 243 |
+
Please confirm your new password.
|
| 244 |
+
</div>
|
| 245 |
+
</div>
|
| 246 |
+
<button type="submit" name="change_password" class="btn btn-warning">
|
| 247 |
+
<i class="fas fa-key me-2"></i> Change Password
|
| 248 |
+
</button>
|
| 249 |
+
</form>
|
| 250 |
+
</div>
|
| 251 |
+
</div>
|
| 252 |
+
</div>
|
| 253 |
+
</div>
|
| 254 |
+
|
| 255 |
+
<style>
|
| 256 |
+
.avatar-circle {
|
| 257 |
+
width: 100px;
|
| 258 |
+
height: 100px;
|
| 259 |
+
background-color: #007bff;
|
| 260 |
+
border-radius: 50%;
|
| 261 |
+
display: flex;
|
| 262 |
+
justify-content: center;
|
| 263 |
+
align-items: center;
|
| 264 |
+
margin: 0 auto;
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
.avatar-text {
|
| 268 |
+
font-size: 48px;
|
| 269 |
+
color: white;
|
| 270 |
+
font-weight: bold;
|
| 271 |
+
}
|
| 272 |
+
</style>
|
| 273 |
+
|
| 274 |
+
<?php
|
| 275 |
+
// Include footer
|
| 276 |
+
include 'includes/footer.php';
|
| 277 |
+
|
| 278 |
+
// Close connection
|
| 279 |
+
$conn->close();
|
| 280 |
+
?>
|
project_add.php
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Ensure only faculty can access this page
|
| 8 |
+
requireFaculty();
|
| 9 |
+
|
| 10 |
+
// Get all domain tables
|
| 11 |
+
$domainTables = getDomainTables($conn);
|
| 12 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 13 |
+
$success = '';
|
| 14 |
+
$error = '';
|
| 15 |
+
|
| 16 |
+
// Process form submission
|
| 17 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 18 |
+
// Validate form data
|
| 19 |
+
$domainNumber = isset($_POST['domain']) ? intval($_POST['domain']) : 0;
|
| 20 |
+
$projectName = isset($_POST['project_name']) ? trim($_POST['project_name']) : '';
|
| 21 |
+
$projectType = isset($_POST['project_type']) ? trim($_POST['project_type']) : '';
|
| 22 |
+
$description = isset($_POST['description']) ? trim($_POST['description']) : '';
|
| 23 |
+
$email = isset($_POST['email']) ? trim($_POST['email']) : '';
|
| 24 |
+
$links = isset($_POST['links']) ? trim($_POST['links']) : '';
|
| 25 |
+
|
| 26 |
+
// Additional fields (if any)
|
| 27 |
+
$additionalFields = [];
|
| 28 |
+
foreach ($_POST as $key => $value) {
|
| 29 |
+
if (strpos($key, 'additional_') === 0) {
|
| 30 |
+
$fieldName = substr($key, 11); // Remove 'additional_' prefix
|
| 31 |
+
$additionalFields[$fieldName] = trim($value);
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// Basic validation
|
| 36 |
+
if ($domainNumber <= 0 || empty($projectName) || empty($projectType)) {
|
| 37 |
+
$error = "Please provide domain, project name, and project type.";
|
| 38 |
+
} else {
|
| 39 |
+
// Determine domain table name
|
| 40 |
+
$domainTable = "domain_" . $domainNumber;
|
| 41 |
+
|
| 42 |
+
// Check if the domain table exists
|
| 43 |
+
$tableCheckQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 44 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 45 |
+
|
| 46 |
+
if (!$tableExists) {
|
| 47 |
+
$error = "Selected domain table does not exist.";
|
| 48 |
+
} else {
|
| 49 |
+
// Get the correct project name field for this domain
|
| 50 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 51 |
+
|
| 52 |
+
// Get the columns of the domain table to determine field structure
|
| 53 |
+
$columnsQuery = "SHOW COLUMNS FROM $domainTable";
|
| 54 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 55 |
+
$columns = [];
|
| 56 |
+
|
| 57 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 58 |
+
$columns[$column['Field']] = $column;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
// Generate a new project ID
|
| 62 |
+
$maxIdQuery = "SELECT MAX(Project_ID) as max_id FROM $domainTable";
|
| 63 |
+
$maxIdResult = $conn->query($maxIdQuery);
|
| 64 |
+
$maxId = 1; // Default if no projects exist
|
| 65 |
+
|
| 66 |
+
if ($maxIdResult && $row = $maxIdResult->fetch_assoc()) {
|
| 67 |
+
$maxId = (!is_null($row['max_id'])) ? intval($row['max_id']) + 1 : 1;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// Prepare the SQL for insertion
|
| 71 |
+
$fields = ['Project_ID'];
|
| 72 |
+
$values = [$maxId];
|
| 73 |
+
$types = 'i'; // integer for Project_ID
|
| 74 |
+
|
| 75 |
+
// Add Domain_ID field if it exists
|
| 76 |
+
if (isset($columns['Domain_ID'])) {
|
| 77 |
+
$fields[] = 'Domain_ID';
|
| 78 |
+
$domainId = "D-" . $domainNumber;
|
| 79 |
+
$values[] = $domainId;
|
| 80 |
+
$types .= 's'; // string for Domain_ID
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
// Add project name field
|
| 84 |
+
$fields[] = $projectNameField;
|
| 85 |
+
$values[] = $projectName;
|
| 86 |
+
$types .= 's'; // string for Project Name
|
| 87 |
+
|
| 88 |
+
// Add project type field (H/S)
|
| 89 |
+
if (isset($columns['H/S'])) {
|
| 90 |
+
$fields[] = 'H/S';
|
| 91 |
+
$values[] = $projectType;
|
| 92 |
+
$types .= 's'; // string for H/S
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
// Add description field
|
| 96 |
+
if (isset($columns['Description']) && !empty($description)) {
|
| 97 |
+
$fields[] = 'Description';
|
| 98 |
+
$values[] = $description;
|
| 99 |
+
$types .= 's'; // string for Description
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
// Add email field
|
| 103 |
+
if (isset($columns['Email']) && !empty($email)) {
|
| 104 |
+
$fields[] = 'Email';
|
| 105 |
+
$values[] = $email;
|
| 106 |
+
$types .= 's'; // string for Email
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
// Add links field
|
| 110 |
+
if (isset($columns['Links']) && !empty($links)) {
|
| 111 |
+
$fields[] = 'Links';
|
| 112 |
+
$values[] = $links;
|
| 113 |
+
$types .= 's'; // string for Links
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
// Add additional fields
|
| 117 |
+
foreach ($additionalFields as $field => $value) {
|
| 118 |
+
if (isset($columns[$field]) && !empty($value)) {
|
| 119 |
+
$fields[] = $field;
|
| 120 |
+
$values[] = $value;
|
| 121 |
+
$types .= 's'; // string for additional fields
|
| 122 |
+
}
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
// Prepare and execute the insert query
|
| 126 |
+
$fieldStr = implode(', ', array_map(function($field) { return "`$field`"; }, $fields));
|
| 127 |
+
$placeholders = implode(', ', array_fill(0, count($fields), '?'));
|
| 128 |
+
|
| 129 |
+
$insertQuery = "INSERT INTO $domainTable ($fieldStr) VALUES ($placeholders)";
|
| 130 |
+
$stmt = $conn->prepare($insertQuery);
|
| 131 |
+
|
| 132 |
+
if ($stmt) {
|
| 133 |
+
// Dynamically bind parameters
|
| 134 |
+
$params = array_merge([$types], $values);
|
| 135 |
+
$ref_params = [];
|
| 136 |
+
|
| 137 |
+
foreach ($params as $key => $value) {
|
| 138 |
+
$ref_params[$key] = &$params[$key];
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
call_user_func_array([$stmt, 'bind_param'], $ref_params);
|
| 142 |
+
|
| 143 |
+
if ($stmt->execute()) {
|
| 144 |
+
$success = "Project added successfully with ID: $maxId";
|
| 145 |
+
|
| 146 |
+
// Clear form after successful submission
|
| 147 |
+
$projectName = $description = $email = $links = '';
|
| 148 |
+
$projectType = '';
|
| 149 |
+
$additionalFields = [];
|
| 150 |
+
} else {
|
| 151 |
+
$error = "Error adding project: " . $stmt->error;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
$stmt->close();
|
| 155 |
+
} else {
|
| 156 |
+
$error = "Error preparing query: " . $conn->error;
|
| 157 |
+
}
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
// Include header
|
| 163 |
+
include 'includes/header.php';
|
| 164 |
+
?>
|
| 165 |
+
|
| 166 |
+
<div class="row mb-4">
|
| 167 |
+
<div class="col-md-12">
|
| 168 |
+
<nav aria-label="breadcrumb">
|
| 169 |
+
<ol class="breadcrumb">
|
| 170 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 171 |
+
<li class="breadcrumb-item"><a href="domains.php">Domains</a></li>
|
| 172 |
+
<li class="breadcrumb-item"><a href="project_manage.php">Manage Projects</a></li>
|
| 173 |
+
<li class="breadcrumb-item active">Add Project</li>
|
| 174 |
+
</ol>
|
| 175 |
+
</nav>
|
| 176 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 177 |
+
<h2><i class="fas fa-plus-circle me-2"></i> Add New Project</h2>
|
| 178 |
+
<a href="project_manage.php" class="btn btn-secondary">
|
| 179 |
+
<i class="fas fa-arrow-left me-1"></i> Back to Projects
|
| 180 |
+
</a>
|
| 181 |
+
</div>
|
| 182 |
+
</div>
|
| 183 |
+
</div>
|
| 184 |
+
|
| 185 |
+
<?php if (!empty($success)): ?>
|
| 186 |
+
<div class="alert alert-success">
|
| 187 |
+
<i class="fas fa-check-circle me-2"></i> <?php echo $success; ?>
|
| 188 |
+
</div>
|
| 189 |
+
<?php endif; ?>
|
| 190 |
+
|
| 191 |
+
<?php if (!empty($error)): ?>
|
| 192 |
+
<div class="alert alert-danger">
|
| 193 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 194 |
+
</div>
|
| 195 |
+
<?php endif; ?>
|
| 196 |
+
|
| 197 |
+
<div class="row">
|
| 198 |
+
<div class="col-md-12">
|
| 199 |
+
<div class="card shadow-sm">
|
| 200 |
+
<div class="card-header bg-primary text-white">
|
| 201 |
+
<h5 class="mb-0"><i class="fas fa-edit me-2"></i> Project Details</h5>
|
| 202 |
+
</div>
|
| 203 |
+
<div class="card-body">
|
| 204 |
+
<form method="post" action="project_add.php" id="projectForm">
|
| 205 |
+
<div class="row">
|
| 206 |
+
<div class="col-md-6 mb-3">
|
| 207 |
+
<label for="domain" class="form-label">Domain *</label>
|
| 208 |
+
<select class="form-select" id="domain" name="domain" required>
|
| 209 |
+
<option value="">Select Domain</option>
|
| 210 |
+
<?php foreach ($domainTables as $domainTable):
|
| 211 |
+
$domainNum = str_replace('domain_', '', $domainTable);
|
| 212 |
+
$domainDesc = isset($domainDescriptions[$domainNum]) ? $domainDescriptions[$domainNum] : "Domain $domainNum";
|
| 213 |
+
?>
|
| 214 |
+
<option value="<?php echo $domainNum; ?>" <?php echo (isset($_POST['domain']) && $_POST['domain'] == $domainNum) ? 'selected' : ''; ?>>
|
| 215 |
+
Domain <?php echo $domainNum; ?>: <?php echo htmlspecialchars($domainDesc); ?>
|
| 216 |
+
</option>
|
| 217 |
+
<?php endforeach; ?>
|
| 218 |
+
</select>
|
| 219 |
+
</div>
|
| 220 |
+
|
| 221 |
+
<div class="col-md-6 mb-3">
|
| 222 |
+
<label for="project_type" class="form-label">Project Type *</label>
|
| 223 |
+
<select class="form-select" id="project_type" name="project_type" required>
|
| 224 |
+
<option value="">Select Type</option>
|
| 225 |
+
<option value="Hardware" <?php echo (isset($_POST['project_type']) && $_POST['project_type'] == 'Hardware') ? 'selected' : ''; ?>>Hardware</option>
|
| 226 |
+
<option value="Software" <?php echo (isset($_POST['project_type']) && $_POST['project_type'] == 'Software') ? 'selected' : ''; ?>>Software</option>
|
| 227 |
+
</select>
|
| 228 |
+
</div>
|
| 229 |
+
</div>
|
| 230 |
+
|
| 231 |
+
<div class="mb-3">
|
| 232 |
+
<label for="project_name" class="form-label">Project Name *</label>
|
| 233 |
+
<input type="text" class="form-control" id="project_name" name="project_name" value="<?php echo htmlspecialchars($projectName ?? ''); ?>" required>
|
| 234 |
+
</div>
|
| 235 |
+
|
| 236 |
+
<div class="mb-3">
|
| 237 |
+
<label for="description" class="form-label">Description</label>
|
| 238 |
+
<textarea class="form-control" id="description" name="description" rows="4"><?php echo htmlspecialchars($description ?? ''); ?></textarea>
|
| 239 |
+
</div>
|
| 240 |
+
|
| 241 |
+
<div class="row">
|
| 242 |
+
<div class="col-md-6 mb-3">
|
| 243 |
+
<label for="email" class="form-label">Contact Email</label>
|
| 244 |
+
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($email ?? ''); ?>">
|
| 245 |
+
</div>
|
| 246 |
+
|
| 247 |
+
<div class="col-md-6 mb-3">
|
| 248 |
+
<label for="links" class="form-label">Links (Comma separated)</label>
|
| 249 |
+
<input type="text" class="form-control" id="links" name="links" value="<?php echo htmlspecialchars($links ?? ''); ?>" placeholder="https://example1.com, https://example2.com">
|
| 250 |
+
</div>
|
| 251 |
+
</div>
|
| 252 |
+
|
| 253 |
+
<div id="additional_fields">
|
| 254 |
+
<!-- Additional fields will be loaded here based on domain selection -->
|
| 255 |
+
</div>
|
| 256 |
+
|
| 257 |
+
<div class="d-grid gap-2 d-md-flex justify-content-md-end mt-4">
|
| 258 |
+
<button type="reset" class="btn btn-outline-secondary">
|
| 259 |
+
<i class="fas fa-undo me-1"></i> Reset
|
| 260 |
+
</button>
|
| 261 |
+
<button type="submit" class="btn btn-primary">
|
| 262 |
+
<i class="fas fa-save me-1"></i> Add Project
|
| 263 |
+
</button>
|
| 264 |
+
</div>
|
| 265 |
+
</form>
|
| 266 |
+
</div>
|
| 267 |
+
</div>
|
| 268 |
+
</div>
|
| 269 |
+
</div>
|
| 270 |
+
|
| 271 |
+
<script>
|
| 272 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 273 |
+
// Function to load additional fields based on domain selection
|
| 274 |
+
function loadAdditionalFields() {
|
| 275 |
+
const domainSelect = document.getElementById('domain');
|
| 276 |
+
const additionalFieldsContainer = document.getElementById('additional_fields');
|
| 277 |
+
const selectedDomain = domainSelect.value;
|
| 278 |
+
|
| 279 |
+
if (!selectedDomain) {
|
| 280 |
+
additionalFieldsContainer.innerHTML = '';
|
| 281 |
+
return;
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
// Show loading indicator
|
| 285 |
+
additionalFieldsContainer.innerHTML = '<div class="text-center my-3"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div></div>';
|
| 286 |
+
|
| 287 |
+
// Use AJAX to get table structure
|
| 288 |
+
fetch('ajax/get_domain_fields.php?domain=' + selectedDomain)
|
| 289 |
+
.then(response => response.json())
|
| 290 |
+
.then(data => {
|
| 291 |
+
let html = '<h5 class="mt-4 mb-3">Additional Fields</h5>';
|
| 292 |
+
|
| 293 |
+
if (data.error) {
|
| 294 |
+
html = `<div class="alert alert-danger mt-3">${data.error}</div>`;
|
| 295 |
+
} else if (data.fields && data.fields.length > 0) {
|
| 296 |
+
data.fields.forEach(field => {
|
| 297 |
+
// Skip standard fields we already have in the form
|
| 298 |
+
if (['Project_ID', 'Domain_ID', 'Project_Name', 'H/S', 'Description', 'Email', 'Links'].includes(field.name)) {
|
| 299 |
+
return;
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
html += `
|
| 303 |
+
<div class="mb-3">
|
| 304 |
+
<label for="additional_${field.name}" class="form-label">${field.name}</label>
|
| 305 |
+
<input type="text" class="form-control" id="additional_${field.name}" name="additional_${field.name}"
|
| 306 |
+
value="${field.value || ''}">
|
| 307 |
+
</div>`;
|
| 308 |
+
});
|
| 309 |
+
} else {
|
| 310 |
+
html = '<div class="alert alert-info mt-3">No additional fields found for this domain.</div>';
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
additionalFieldsContainer.innerHTML = html;
|
| 314 |
+
})
|
| 315 |
+
.catch(error => {
|
| 316 |
+
additionalFieldsContainer.innerHTML = `<div class="alert alert-danger mt-3">Error loading fields: ${error.message}</div>`;
|
| 317 |
+
});
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
// Initialize
|
| 321 |
+
const domainSelect = document.getElementById('domain');
|
| 322 |
+
domainSelect.addEventListener('change', loadAdditionalFields);
|
| 323 |
+
|
| 324 |
+
// Load fields if domain is already selected (e.g., after form validation failure)
|
| 325 |
+
if (domainSelect.value) {
|
| 326 |
+
loadAdditionalFields();
|
| 327 |
+
}
|
| 328 |
+
});
|
| 329 |
+
</script>
|
| 330 |
+
|
| 331 |
+
<?php
|
| 332 |
+
// Include footer
|
| 333 |
+
include 'includes/footer.php';
|
| 334 |
+
|
| 335 |
+
// Close connection
|
| 336 |
+
$conn->close();
|
| 337 |
+
?>
|
project_delete.php
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Ensure only faculty can access this page
|
| 8 |
+
requireFaculty();
|
| 9 |
+
|
| 10 |
+
// Initialize variables
|
| 11 |
+
$error = '';
|
| 12 |
+
$domainNumber = isset($_GET['domain']) ? intval($_GET['domain']) : 0;
|
| 13 |
+
$projectId = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
| 14 |
+
$confirm = isset($_GET['confirm']) && $_GET['confirm'] === 'yes';
|
| 15 |
+
$projectName = '';
|
| 16 |
+
$domainTable = "domain_" . $domainNumber;
|
| 17 |
+
|
| 18 |
+
// Get domain descriptions
|
| 19 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 20 |
+
$domainDescription = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : "Domain $domainNumber";
|
| 21 |
+
|
| 22 |
+
// Check if the domain and project ID are provided
|
| 23 |
+
if ($domainNumber <= 0 || $projectId <= 0) {
|
| 24 |
+
$error = "Invalid domain or project ID.";
|
| 25 |
+
} else {
|
| 26 |
+
// Check if the domain table exists
|
| 27 |
+
$tableCheckQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 28 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 29 |
+
|
| 30 |
+
if (!$tableExists) {
|
| 31 |
+
$error = "Domain table does not exist.";
|
| 32 |
+
} else {
|
| 33 |
+
// Get project name field for this domain
|
| 34 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 35 |
+
|
| 36 |
+
// Get the project details
|
| 37 |
+
$projectQuery = "SELECT `$projectNameField` FROM $domainTable WHERE Project_ID = ? LIMIT 1";
|
| 38 |
+
$stmt = $conn->prepare($projectQuery);
|
| 39 |
+
|
| 40 |
+
if ($stmt) {
|
| 41 |
+
$stmt->bind_param('i', $projectId);
|
| 42 |
+
$stmt->execute();
|
| 43 |
+
$result = $stmt->get_result();
|
| 44 |
+
|
| 45 |
+
if ($result && $result->num_rows > 0) {
|
| 46 |
+
$project = $result->fetch_assoc();
|
| 47 |
+
$projectName = $project[$projectNameField];
|
| 48 |
+
|
| 49 |
+
// If confirmed, delete the project
|
| 50 |
+
if ($confirm) {
|
| 51 |
+
$deleteQuery = "DELETE FROM $domainTable WHERE Project_ID = ?";
|
| 52 |
+
$deleteStmt = $conn->prepare($deleteQuery);
|
| 53 |
+
|
| 54 |
+
if ($deleteStmt) {
|
| 55 |
+
$deleteStmt->bind_param('i', $projectId);
|
| 56 |
+
|
| 57 |
+
if ($deleteStmt->execute()) {
|
| 58 |
+
// Redirect to project management page with success message
|
| 59 |
+
header("Location: project_manage.php?deleted=1&project=" . urlencode($projectName));
|
| 60 |
+
exit;
|
| 61 |
+
} else {
|
| 62 |
+
$error = "Error deleting project: " . $deleteStmt->error;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
$deleteStmt->close();
|
| 66 |
+
} else {
|
| 67 |
+
$error = "Error preparing delete query: " . $conn->error;
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
} else {
|
| 71 |
+
$error = "Project not found.";
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
$stmt->close();
|
| 75 |
+
} else {
|
| 76 |
+
$error = "Error preparing query: " . $conn->error;
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
// Include header
|
| 82 |
+
include 'includes/header.php';
|
| 83 |
+
?>
|
| 84 |
+
|
| 85 |
+
<div class="row mb-4">
|
| 86 |
+
<div class="col-md-12">
|
| 87 |
+
<nav aria-label="breadcrumb">
|
| 88 |
+
<ol class="breadcrumb">
|
| 89 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 90 |
+
<li class="breadcrumb-item"><a href="project_manage.php">Manage Projects</a></li>
|
| 91 |
+
<li class="breadcrumb-item active">Delete Project</li>
|
| 92 |
+
</ol>
|
| 93 |
+
</nav>
|
| 94 |
+
<h2><i class="fas fa-trash-alt me-2"></i> Delete Project</h2>
|
| 95 |
+
</div>
|
| 96 |
+
</div>
|
| 97 |
+
|
| 98 |
+
<?php if (!empty($error)): ?>
|
| 99 |
+
<div class="alert alert-danger">
|
| 100 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 101 |
+
<div class="mt-3">
|
| 102 |
+
<a href="project_manage.php" class="btn btn-primary">
|
| 103 |
+
<i class="fas fa-arrow-left me-1"></i> Back to Project Management
|
| 104 |
+
</a>
|
| 105 |
+
</div>
|
| 106 |
+
</div>
|
| 107 |
+
<?php elseif (!$confirm): ?>
|
| 108 |
+
<div class="row">
|
| 109 |
+
<div class="col-md-8 mx-auto">
|
| 110 |
+
<div class="card shadow-sm border-danger">
|
| 111 |
+
<div class="card-header bg-danger text-white">
|
| 112 |
+
<h5 class="mb-0"><i class="fas fa-exclamation-triangle me-2"></i> Confirm Deletion</h5>
|
| 113 |
+
</div>
|
| 114 |
+
<div class="card-body">
|
| 115 |
+
<p class="alert alert-warning">
|
| 116 |
+
<i class="fas fa-exclamation-circle me-2"></i> <strong>Warning:</strong> You are about to delete the following project:
|
| 117 |
+
</p>
|
| 118 |
+
|
| 119 |
+
<div class="card mb-4">
|
| 120 |
+
<div class="card-body">
|
| 121 |
+
<h5 class="card-title"><?php echo htmlspecialchars($projectName); ?></h5>
|
| 122 |
+
<p class="card-text">
|
| 123 |
+
<strong>Domain:</strong> <?php echo htmlspecialchars("Domain $domainNumber: $domainDescription"); ?>
|
| 124 |
+
</p>
|
| 125 |
+
<p class="card-text">
|
| 126 |
+
<strong>Project ID:</strong> <?php echo $projectId; ?>
|
| 127 |
+
</p>
|
| 128 |
+
</div>
|
| 129 |
+
</div>
|
| 130 |
+
|
| 131 |
+
<p class="text-danger"><strong>This action cannot be undone.</strong> Are you sure you want to delete this project?</p>
|
| 132 |
+
|
| 133 |
+
<div class="d-flex justify-content-between mt-4">
|
| 134 |
+
<a href="project_manage.php" class="btn btn-secondary">
|
| 135 |
+
<i class="fas fa-times me-1"></i> Cancel
|
| 136 |
+
</a>
|
| 137 |
+
<a href="project_delete.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($projectId); ?>&confirm=yes" class="btn btn-danger">
|
| 138 |
+
<i class="fas fa-trash-alt me-1"></i> Yes, Delete Project
|
| 139 |
+
</a>
|
| 140 |
+
</div>
|
| 141 |
+
</div>
|
| 142 |
+
</div>
|
| 143 |
+
</div>
|
| 144 |
+
</div>
|
| 145 |
+
<?php endif; ?>
|
| 146 |
+
|
| 147 |
+
<?php
|
| 148 |
+
// Include footer
|
| 149 |
+
include 'includes/footer.php';
|
| 150 |
+
|
| 151 |
+
// Close connection
|
| 152 |
+
$conn->close();
|
| 153 |
+
?>
|
project_details.php
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Validate the parameters
|
| 8 |
+
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
| 9 |
+
header("Location: index.php");
|
| 10 |
+
exit;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
$projectId = $_GET['id'];
|
| 14 |
+
$domainNumber = isset($_GET['domain']) ? $_GET['domain'] : null;
|
| 15 |
+
|
| 16 |
+
// Get domain descriptions from utility function
|
| 17 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 18 |
+
|
| 19 |
+
// If domain number is not provided, find it by searching all domain tables
|
| 20 |
+
if ($domainNumber === null) {
|
| 21 |
+
$domainTables = getDomainTables($conn);
|
| 22 |
+
|
| 23 |
+
foreach ($domainTables as $domainTable) {
|
| 24 |
+
// Check for project in this domain
|
| 25 |
+
$checkQuery = "SELECT * FROM $domainTable WHERE Project_ID = $projectId LIMIT 1";
|
| 26 |
+
$checkResult = $conn->query($checkQuery);
|
| 27 |
+
|
| 28 |
+
if ($checkResult && $checkResult->num_rows > 0) {
|
| 29 |
+
$domainNumber = str_replace('domain_', '', $domainTable);
|
| 30 |
+
break;
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// If still not found, redirect
|
| 35 |
+
if ($domainNumber === null) {
|
| 36 |
+
header("Location: index.php");
|
| 37 |
+
exit;
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
$domainTable = "domain_" . $domainNumber;
|
| 42 |
+
|
| 43 |
+
// Get domain description
|
| 44 |
+
$domainDescription = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : 'Domain ' . $domainNumber;
|
| 45 |
+
|
| 46 |
+
// Check if table exists
|
| 47 |
+
$tableExistsQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 48 |
+
$tableExists = $conn->query($tableExistsQuery)->num_rows > 0;
|
| 49 |
+
|
| 50 |
+
if (!$tableExists) {
|
| 51 |
+
header("Location: index.php");
|
| 52 |
+
exit;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
// Fetch project details
|
| 56 |
+
$projectQuery = "SELECT * FROM $domainTable WHERE Project_ID = $projectId LIMIT 1";
|
| 57 |
+
$projectResult = $conn->query($projectQuery);
|
| 58 |
+
|
| 59 |
+
if (!$projectResult || $projectResult->num_rows === 0) {
|
| 60 |
+
header("Location: domain_projects.php?domain=$domainNumber");
|
| 61 |
+
exit;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
$project = $projectResult->fetch_assoc();
|
| 65 |
+
|
| 66 |
+
// Get the correct project name field
|
| 67 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 68 |
+
|
| 69 |
+
// Get project name using the correct field
|
| 70 |
+
$projectName = $project[$projectNameField];
|
| 71 |
+
|
| 72 |
+
// Fetch students associated with this project if students_info table exists
|
| 73 |
+
$studentsQuery = "SHOW TABLES LIKE 'students_info'";
|
| 74 |
+
$studentsTableExists = $conn->query($studentsQuery)->num_rows > 0;
|
| 75 |
+
|
| 76 |
+
$students = [];
|
| 77 |
+
if ($studentsTableExists) {
|
| 78 |
+
$studentsQuery = "SELECT * FROM students_info WHERE Project_ID = $projectId";
|
| 79 |
+
$studentsResult = $conn->query($studentsQuery);
|
| 80 |
+
|
| 81 |
+
if ($studentsResult && $studentsResult->num_rows > 0) {
|
| 82 |
+
while ($student = $studentsResult->fetch_assoc()) {
|
| 83 |
+
$students[] = $student;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
// Include header
|
| 89 |
+
include 'includes/header.php';
|
| 90 |
+
?>
|
| 91 |
+
|
| 92 |
+
<div class="row mb-4">
|
| 93 |
+
<div class="col-md-12">
|
| 94 |
+
<nav aria-label="breadcrumb">
|
| 95 |
+
<ol class="breadcrumb">
|
| 96 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 97 |
+
<?php if (!$is_student): ?>
|
| 98 |
+
<li class="breadcrumb-item"><a href="domains.php">Domains</a></li>
|
| 99 |
+
<li class="breadcrumb-item"><a href="domain_projects.php?domain=<?php echo $domainNumber; ?>">Domain <?php echo $domainNumber; ?></a></li>
|
| 100 |
+
<?php endif; ?>
|
| 101 |
+
<li class="breadcrumb-item active">Project <?php echo $projectId; ?></li>
|
| 102 |
+
</ol>
|
| 103 |
+
</nav>
|
| 104 |
+
</div>
|
| 105 |
+
</div>
|
| 106 |
+
|
| 107 |
+
<div class="row mb-4">
|
| 108 |
+
<div class="col-md-12">
|
| 109 |
+
<div class="card shadow-sm">
|
| 110 |
+
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
|
| 111 |
+
<h4 class="mb-0"><i class="fas fa-project-diagram me-2"></i> Project Details</h4>
|
| 112 |
+
<?php if ($is_faculty): ?>
|
| 113 |
+
<div class="btn-group">
|
| 114 |
+
<a href="project_edit.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($projectId); ?>" class="btn btn-light btn-sm">
|
| 115 |
+
<i class="fas fa-edit me-1"></i> Edit Project
|
| 116 |
+
</a>
|
| 117 |
+
<a href="project_delete.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($projectId); ?>" class="btn btn-danger btn-sm">
|
| 118 |
+
<i class="fas fa-trash-alt me-1"></i> Delete Project
|
| 119 |
+
</a>
|
| 120 |
+
</div>
|
| 121 |
+
<?php endif; ?>
|
| 122 |
+
</div>
|
| 123 |
+
<div class="card-body">
|
| 124 |
+
<h2 class="card-title"><?php echo htmlspecialchars($projectName); ?></h2>
|
| 125 |
+
<h6 class="card-subtitle mb-3 text-muted">
|
| 126 |
+
<span class="badge bg-secondary me-2">Domain <?php echo htmlspecialchars($domainNumber); ?>: <?php echo htmlspecialchars($domainDescription); ?></span>
|
| 127 |
+
<?php if (isset($project['H/S'])): ?>
|
| 128 |
+
<span class="badge bg-<?php echo strtolower($project['H/S']) === 'h' ? 'warning' : 'info'; ?>">
|
| 129 |
+
<?php echo strtolower($project['H/S']) === 'h' ? 'Hardware' : 'Software'; ?>
|
| 130 |
+
</span>
|
| 131 |
+
<?php endif; ?>
|
| 132 |
+
</h6>
|
| 133 |
+
|
| 134 |
+
<div class="row">
|
| 135 |
+
<div class="col-md-8">
|
| 136 |
+
<div class="card mb-3">
|
| 137 |
+
<div class="card-header bg-light">
|
| 138 |
+
<h5 class="mb-0"><i class="fas fa-align-left me-2"></i> Description</h5>
|
| 139 |
+
</div>
|
| 140 |
+
<div class="card-body">
|
| 141 |
+
<p><?php echo nl2br(htmlspecialchars($project['Description'])); ?></p>
|
| 142 |
+
</div>
|
| 143 |
+
</div>
|
| 144 |
+
|
| 145 |
+
<?php if (!empty($project['Email'])): ?>
|
| 146 |
+
<div class="card mb-3">
|
| 147 |
+
<div class="card-header bg-light">
|
| 148 |
+
<h5 class="mb-0"><i class="fas fa-envelope me-2"></i> Contact</h5>
|
| 149 |
+
</div>
|
| 150 |
+
<div class="card-body">
|
| 151 |
+
<p><strong>Email:</strong> <?php echo htmlspecialchars($project['Email']); ?></p>
|
| 152 |
+
</div>
|
| 153 |
+
</div>
|
| 154 |
+
<?php endif; ?>
|
| 155 |
+
|
| 156 |
+
<?php if (!empty($project['Links'])): ?>
|
| 157 |
+
<div class="card mb-3">
|
| 158 |
+
<div class="card-header bg-light">
|
| 159 |
+
<h5 class="mb-0"><i class="fas fa-link me-2"></i> Resources</h5>
|
| 160 |
+
</div>
|
| 161 |
+
<div class="card-body">
|
| 162 |
+
<?php
|
| 163 |
+
$links = explode(',', $project['Links']);
|
| 164 |
+
foreach ($links as $link) {
|
| 165 |
+
$link = trim($link);
|
| 166 |
+
echo '<a href="' . htmlspecialchars($link) . '" class="btn btn-sm btn-outline-primary me-2 mb-2" target="_blank">';
|
| 167 |
+
echo '<i class="fas fa-external-link-alt me-1"></i> View Resource</a>';
|
| 168 |
+
}
|
| 169 |
+
?>
|
| 170 |
+
</div>
|
| 171 |
+
</div>
|
| 172 |
+
<?php endif; ?>
|
| 173 |
+
</div>
|
| 174 |
+
|
| 175 |
+
<div class="col-md-4">
|
| 176 |
+
<div class="card">
|
| 177 |
+
<div class="card-header bg-light">
|
| 178 |
+
<h5 class="mb-0"><i class="fas fa-info-circle me-2"></i> Project Info</h5>
|
| 179 |
+
</div>
|
| 180 |
+
<ul class="list-group list-group-flush">
|
| 181 |
+
<li class="list-group-item"><strong>Project ID:</strong> <?php echo htmlspecialchars($project['Project_ID']); ?></li>
|
| 182 |
+
<li class="list-group-item"><strong>Domain ID:</strong> <?php echo htmlspecialchars($project['Domain_ID']); ?></li>
|
| 183 |
+
<?php foreach ($project as $key => $value):
|
| 184 |
+
// Skip already displayed fields and empty values
|
| 185 |
+
if (in_array($key, [$projectNameField, 'Description', 'Email', 'Links', 'Project_ID', 'Domain_ID', 'H/S']) || empty($value)) {
|
| 186 |
+
continue;
|
| 187 |
+
}
|
| 188 |
+
?>
|
| 189 |
+
<li class="list-group-item"><strong><?php echo htmlspecialchars($key); ?>:</strong> <?php echo htmlspecialchars($value); ?></li>
|
| 190 |
+
<?php endforeach; ?>
|
| 191 |
+
</ul>
|
| 192 |
+
</div>
|
| 193 |
+
</div>
|
| 194 |
+
</div>
|
| 195 |
+
</div>
|
| 196 |
+
</div>
|
| 197 |
+
</div>
|
| 198 |
+
</div>
|
| 199 |
+
|
| 200 |
+
<?php if ($is_faculty && !empty($students)): ?>
|
| 201 |
+
<div class="row">
|
| 202 |
+
<div class="col-md-12">
|
| 203 |
+
<div class="card shadow-sm">
|
| 204 |
+
<div class="card-header bg-info text-white">
|
| 205 |
+
<h5 class="mb-0"><i class="fas fa-users me-2"></i> Team Members</h5>
|
| 206 |
+
</div>
|
| 207 |
+
<div class="card-body">
|
| 208 |
+
<div class="table-responsive">
|
| 209 |
+
<table class="table table-striped table-hover">
|
| 210 |
+
<thead class="table-light">
|
| 211 |
+
<tr>
|
| 212 |
+
<th>Student ID</th>
|
| 213 |
+
<th>Name</th>
|
| 214 |
+
<th>Division</th>
|
| 215 |
+
<th>Roll No.</th>
|
| 216 |
+
<th>Email</th>
|
| 217 |
+
<th>Phone</th>
|
| 218 |
+
</tr>
|
| 219 |
+
</thead>
|
| 220 |
+
<tbody>
|
| 221 |
+
<?php foreach ($students as $student): ?>
|
| 222 |
+
<tr>
|
| 223 |
+
<td><?php echo htmlspecialchars($student['Student_ID']); ?></td>
|
| 224 |
+
<td><?php echo htmlspecialchars($student['Name']); ?></td>
|
| 225 |
+
<td><?php echo htmlspecialchars($student['Division']); ?></td>
|
| 226 |
+
<td><?php echo htmlspecialchars($student['Roll_No']); ?></td>
|
| 227 |
+
<td><?php echo htmlspecialchars($student['Email_ID']); ?></td>
|
| 228 |
+
<td><?php echo htmlspecialchars($student['Phone_Number']); ?></td>
|
| 229 |
+
</tr>
|
| 230 |
+
<?php endforeach; ?>
|
| 231 |
+
</tbody>
|
| 232 |
+
</table>
|
| 233 |
+
</div>
|
| 234 |
+
</div>
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
</div>
|
| 238 |
+
<?php elseif ($is_student && !empty($students)): ?>
|
| 239 |
+
<div class="row">
|
| 240 |
+
<div class="col-md-12">
|
| 241 |
+
<div class="card shadow-sm">
|
| 242 |
+
<div class="card-header bg-info text-white">
|
| 243 |
+
<h5 class="mb-0"><i class="fas fa-info-circle me-2"></i> Project Information</h5>
|
| 244 |
+
</div>
|
| 245 |
+
<div class="card-body">
|
| 246 |
+
<div class="alert alert-info">
|
| 247 |
+
<i class="fas fa-info-circle me-2"></i> This project has team members assigned. Contact your faculty advisor for more information.
|
| 248 |
+
</div>
|
| 249 |
+
</div>
|
| 250 |
+
</div>
|
| 251 |
+
</div>
|
| 252 |
+
</div>
|
| 253 |
+
<?php endif; ?>
|
| 254 |
+
|
| 255 |
+
<?php if ($is_faculty): ?>
|
| 256 |
+
<div class="row mt-4">
|
| 257 |
+
<div class="col-md-12">
|
| 258 |
+
<div class="d-flex justify-content-end">
|
| 259 |
+
<a href="project_manage.php" class="btn btn-secondary me-2">
|
| 260 |
+
<i class="fas fa-list me-1"></i> All Projects
|
| 261 |
+
</a>
|
| 262 |
+
<a href="project_edit.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($projectId); ?>" class="btn btn-primary me-2">
|
| 263 |
+
<i class="fas fa-edit me-1"></i> Edit Project
|
| 264 |
+
</a>
|
| 265 |
+
<a href="project_delete.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($projectId); ?>" class="btn btn-danger">
|
| 266 |
+
<i class="fas fa-trash-alt me-1"></i> Delete Project
|
| 267 |
+
</a>
|
| 268 |
+
</div>
|
| 269 |
+
</div>
|
| 270 |
+
</div>
|
| 271 |
+
<?php endif; ?>
|
| 272 |
+
|
| 273 |
+
<?php
|
| 274 |
+
// Include footer
|
| 275 |
+
include 'includes/footer.php';
|
| 276 |
+
|
| 277 |
+
// Close connection
|
| 278 |
+
$conn->close();
|
| 279 |
+
?>
|
project_edit.php
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Ensure only faculty can access this page
|
| 8 |
+
requireFaculty();
|
| 9 |
+
|
| 10 |
+
// Check if domain and project ID are provided
|
| 11 |
+
if (!isset($_GET['domain']) || !isset($_GET['id'])) {
|
| 12 |
+
header("Location: project_manage.php");
|
| 13 |
+
exit;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
$domainNumber = intval($_GET['domain']);
|
| 17 |
+
$projectId = intval($_GET['id']);
|
| 18 |
+
$domainTable = "domain_" . $domainNumber;
|
| 19 |
+
|
| 20 |
+
// Initialize variables
|
| 21 |
+
$success = '';
|
| 22 |
+
$error = '';
|
| 23 |
+
$project = null;
|
| 24 |
+
|
| 25 |
+
// Check if the domain table exists
|
| 26 |
+
$tableCheckQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 27 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 28 |
+
|
| 29 |
+
if (!$tableExists) {
|
| 30 |
+
$error = "Domain table does not exist.";
|
| 31 |
+
} else {
|
| 32 |
+
// Get the correct project name field for this domain
|
| 33 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 34 |
+
|
| 35 |
+
// Get the columns of the domain table to determine field structure
|
| 36 |
+
$columnsQuery = "SHOW COLUMNS FROM $domainTable";
|
| 37 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 38 |
+
$columns = [];
|
| 39 |
+
|
| 40 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 41 |
+
$columns[$column['Field']] = $column;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// Process form submission
|
| 45 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 46 |
+
// Validate form data
|
| 47 |
+
$projectName = isset($_POST['project_name']) ? trim($_POST['project_name']) : '';
|
| 48 |
+
$projectType = isset($_POST['project_type']) ? trim($_POST['project_type']) : '';
|
| 49 |
+
$description = isset($_POST['description']) ? trim($_POST['description']) : '';
|
| 50 |
+
$email = isset($_POST['email']) ? trim($_POST['email']) : '';
|
| 51 |
+
$links = isset($_POST['links']) ? trim($_POST['links']) : '';
|
| 52 |
+
|
| 53 |
+
// Additional fields (if any)
|
| 54 |
+
$additionalFields = [];
|
| 55 |
+
foreach ($_POST as $key => $value) {
|
| 56 |
+
if (strpos($key, 'additional_') === 0) {
|
| 57 |
+
$fieldName = substr($key, 11); // Remove 'additional_' prefix
|
| 58 |
+
$additionalFields[$fieldName] = trim($value);
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
// Basic validation
|
| 63 |
+
if (empty($projectName) || empty($projectType)) {
|
| 64 |
+
$error = "Please provide project name and project type.";
|
| 65 |
+
} else {
|
| 66 |
+
// Prepare the SQL for update
|
| 67 |
+
$updates = [];
|
| 68 |
+
$values = [];
|
| 69 |
+
$types = '';
|
| 70 |
+
|
| 71 |
+
// Add project name field
|
| 72 |
+
$updates[] = "`$projectNameField` = ?";
|
| 73 |
+
$values[] = $projectName;
|
| 74 |
+
$types .= 's'; // string for Project Name
|
| 75 |
+
|
| 76 |
+
// Add project type field (H/S)
|
| 77 |
+
if (isset($columns['H/S'])) {
|
| 78 |
+
$updates[] = "`H/S` = ?";
|
| 79 |
+
$values[] = $projectType;
|
| 80 |
+
$types .= 's'; // string for H/S
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
// Add description field
|
| 84 |
+
if (isset($columns['Description'])) {
|
| 85 |
+
$updates[] = "`Description` = ?";
|
| 86 |
+
$values[] = $description;
|
| 87 |
+
$types .= 's'; // string for Description
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
// Add email field
|
| 91 |
+
if (isset($columns['Email'])) {
|
| 92 |
+
$updates[] = "`Email` = ?";
|
| 93 |
+
$values[] = $email;
|
| 94 |
+
$types .= 's'; // string for Email
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
// Add links field
|
| 98 |
+
if (isset($columns['Links'])) {
|
| 99 |
+
$updates[] = "`Links` = ?";
|
| 100 |
+
$values[] = $links;
|
| 101 |
+
$types .= 's'; // string for Links
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
// Add additional fields
|
| 105 |
+
foreach ($additionalFields as $field => $value) {
|
| 106 |
+
if (isset($columns[$field])) {
|
| 107 |
+
$updates[] = "`$field` = ?";
|
| 108 |
+
$values[] = $value;
|
| 109 |
+
$types .= 's'; // string for additional fields
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
// Add project ID for WHERE clause
|
| 114 |
+
$values[] = $projectId;
|
| 115 |
+
$types .= 'i'; // integer for Project_ID
|
| 116 |
+
|
| 117 |
+
// Prepare and execute the update query
|
| 118 |
+
$updateQuery = "UPDATE $domainTable SET " . implode(', ', $updates) . " WHERE Project_ID = ?";
|
| 119 |
+
$stmt = $conn->prepare($updateQuery);
|
| 120 |
+
|
| 121 |
+
if ($stmt) {
|
| 122 |
+
// Dynamically bind parameters
|
| 123 |
+
$bindParams = array_merge([$types], $values);
|
| 124 |
+
$ref_params = [];
|
| 125 |
+
|
| 126 |
+
foreach ($bindParams as $key => $value) {
|
| 127 |
+
$ref_params[$key] = &$bindParams[$key];
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
call_user_func_array([$stmt, 'bind_param'], $ref_params);
|
| 131 |
+
|
| 132 |
+
if ($stmt->execute()) {
|
| 133 |
+
$success = "Project updated successfully.";
|
| 134 |
+
|
| 135 |
+
// Refresh project data
|
| 136 |
+
$projectQuery = "SELECT * FROM $domainTable WHERE Project_ID = ? LIMIT 1";
|
| 137 |
+
$projectStmt = $conn->prepare($projectQuery);
|
| 138 |
+
$projectStmt->bind_param('i', $projectId);
|
| 139 |
+
$projectStmt->execute();
|
| 140 |
+
$projectResult = $projectStmt->get_result();
|
| 141 |
+
$project = $projectResult->fetch_assoc();
|
| 142 |
+
$projectStmt->close();
|
| 143 |
+
} else {
|
| 144 |
+
$error = "Error updating project: " . $stmt->error;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
$stmt->close();
|
| 148 |
+
} else {
|
| 149 |
+
$error = "Error preparing query: " . $conn->error;
|
| 150 |
+
}
|
| 151 |
+
}
|
| 152 |
+
} else {
|
| 153 |
+
// Fetch project details
|
| 154 |
+
$projectQuery = "SELECT * FROM $domainTable WHERE Project_ID = ? LIMIT 1";
|
| 155 |
+
$stmt = $conn->prepare($projectQuery);
|
| 156 |
+
$stmt->bind_param('i', $projectId);
|
| 157 |
+
$stmt->execute();
|
| 158 |
+
$result = $stmt->get_result();
|
| 159 |
+
|
| 160 |
+
if ($result && $result->num_rows > 0) {
|
| 161 |
+
$project = $result->fetch_assoc();
|
| 162 |
+
} else {
|
| 163 |
+
$error = "Project not found.";
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
$stmt->close();
|
| 167 |
+
}
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
// Get domain descriptions
|
| 171 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 172 |
+
$domainDescription = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : "Domain $domainNumber";
|
| 173 |
+
|
| 174 |
+
// Include header
|
| 175 |
+
include 'includes/header.php';
|
| 176 |
+
?>
|
| 177 |
+
|
| 178 |
+
<div class="row mb-4">
|
| 179 |
+
<div class="col-md-12">
|
| 180 |
+
<nav aria-label="breadcrumb">
|
| 181 |
+
<ol class="breadcrumb">
|
| 182 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 183 |
+
<li class="breadcrumb-item"><a href="project_manage.php">Manage Projects</a></li>
|
| 184 |
+
<li class="breadcrumb-item active">Edit Project</li>
|
| 185 |
+
</ol>
|
| 186 |
+
</nav>
|
| 187 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 188 |
+
<h2><i class="fas fa-edit me-2"></i> Edit Project</h2>
|
| 189 |
+
<div>
|
| 190 |
+
<a href="project_details.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($projectId); ?>" class="btn btn-info">
|
| 191 |
+
<i class="fas fa-eye me-1"></i> View Project
|
| 192 |
+
</a>
|
| 193 |
+
<a href="project_manage.php" class="btn btn-secondary">
|
| 194 |
+
<i class="fas fa-arrow-left me-1"></i> Back to List
|
| 195 |
+
</a>
|
| 196 |
+
</div>
|
| 197 |
+
</div>
|
| 198 |
+
</div>
|
| 199 |
+
</div>
|
| 200 |
+
|
| 201 |
+
<?php if (!empty($success)): ?>
|
| 202 |
+
<div class="alert alert-success">
|
| 203 |
+
<i class="fas fa-check-circle me-2"></i> <?php echo $success; ?>
|
| 204 |
+
</div>
|
| 205 |
+
<?php endif; ?>
|
| 206 |
+
|
| 207 |
+
<?php if (!empty($error)): ?>
|
| 208 |
+
<div class="alert alert-danger">
|
| 209 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 210 |
+
</div>
|
| 211 |
+
<?php endif; ?>
|
| 212 |
+
|
| 213 |
+
<?php if ($project): ?>
|
| 214 |
+
<div class="row">
|
| 215 |
+
<div class="col-md-12">
|
| 216 |
+
<div class="card shadow-sm">
|
| 217 |
+
<div class="card-header bg-primary text-white">
|
| 218 |
+
<h5 class="mb-0"><i class="fas fa-edit me-2"></i> Project Details</h5>
|
| 219 |
+
</div>
|
| 220 |
+
<div class="card-body">
|
| 221 |
+
<form method="post" action="project_edit.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($projectId); ?>" id="projectForm">
|
| 222 |
+
<div class="row">
|
| 223 |
+
<div class="col-md-6 mb-3">
|
| 224 |
+
<label class="form-label">Domain</label>
|
| 225 |
+
<input type="text" class="form-control" value="Domain <?php echo htmlspecialchars($domainNumber); ?>: <?php echo htmlspecialchars($domainDescription); ?>" disabled>
|
| 226 |
+
</div>
|
| 227 |
+
|
| 228 |
+
<div class="col-md-6 mb-3">
|
| 229 |
+
<label for="project_type" class="form-label">Project Type *</label>
|
| 230 |
+
<select class="form-select" id="project_type" name="project_type" required>
|
| 231 |
+
<option value="">Select Type</option>
|
| 232 |
+
<option value="Hardware" <?php echo (isset($project['H/S']) && $project['H/S'] === 'Hardware') ? 'selected' : ''; ?>>Hardware</option>
|
| 233 |
+
<option value="Software" <?php echo (isset($project['H/S']) && $project['H/S'] === 'Software') ? 'selected' : ''; ?>>Software</option>
|
| 234 |
+
</select>
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
|
| 238 |
+
<div class="mb-3">
|
| 239 |
+
<label for="project_name" class="form-label">Project Name *</label>
|
| 240 |
+
<input type="text" class="form-control" id="project_name" name="project_name" value="<?php echo htmlspecialchars($project[$projectNameField]); ?>" required>
|
| 241 |
+
</div>
|
| 242 |
+
|
| 243 |
+
<div class="mb-3">
|
| 244 |
+
<label for="description" class="form-label">Description</label>
|
| 245 |
+
<textarea class="form-control" id="description" name="description" rows="4"><?php echo htmlspecialchars($project['Description'] ?? ''); ?></textarea>
|
| 246 |
+
</div>
|
| 247 |
+
|
| 248 |
+
<div class="row">
|
| 249 |
+
<div class="col-md-6 mb-3">
|
| 250 |
+
<label for="email" class="form-label">Contact Email</label>
|
| 251 |
+
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($project['Email'] ?? ''); ?>">
|
| 252 |
+
</div>
|
| 253 |
+
|
| 254 |
+
<div class="col-md-6 mb-3">
|
| 255 |
+
<label for="links" class="form-label">Links (Comma separated)</label>
|
| 256 |
+
<input type="text" class="form-control" id="links" name="links" value="<?php echo htmlspecialchars($project['Links'] ?? ''); ?>" placeholder="https://example1.com, https://example2.com">
|
| 257 |
+
</div>
|
| 258 |
+
</div>
|
| 259 |
+
|
| 260 |
+
<div id="additional_fields">
|
| 261 |
+
<?php foreach ($project as $field => $value): ?>
|
| 262 |
+
<?php if (!in_array($field, ['Project_ID', 'Domain_ID', $projectNameField, 'H/S', 'Description', 'Email', 'Links']) && !empty($field)): ?>
|
| 263 |
+
<div class="mb-3">
|
| 264 |
+
<label for="additional_<?php echo htmlspecialchars($field); ?>" class="form-label"><?php echo htmlspecialchars($field); ?></label>
|
| 265 |
+
<input type="text" class="form-control" id="additional_<?php echo htmlspecialchars($field); ?>" name="additional_<?php echo htmlspecialchars($field); ?>" value="<?php echo htmlspecialchars($value); ?>">
|
| 266 |
+
</div>
|
| 267 |
+
<?php endif; ?>
|
| 268 |
+
<?php endforeach; ?>
|
| 269 |
+
</div>
|
| 270 |
+
|
| 271 |
+
<div class="d-grid gap-2 d-md-flex justify-content-md-end mt-4">
|
| 272 |
+
<a href="project_manage.php" class="btn btn-secondary">
|
| 273 |
+
<i class="fas fa-times me-1"></i> Cancel
|
| 274 |
+
</a>
|
| 275 |
+
<button type="submit" class="btn btn-primary">
|
| 276 |
+
<i class="fas fa-save me-1"></i> Save Changes
|
| 277 |
+
</button>
|
| 278 |
+
</div>
|
| 279 |
+
</form>
|
| 280 |
+
</div>
|
| 281 |
+
</div>
|
| 282 |
+
</div>
|
| 283 |
+
</div>
|
| 284 |
+
<?php endif; ?>
|
| 285 |
+
|
| 286 |
+
<?php
|
| 287 |
+
// Include footer
|
| 288 |
+
include 'includes/footer.php';
|
| 289 |
+
|
| 290 |
+
// Close connection
|
| 291 |
+
$conn->close();
|
| 292 |
+
?>
|
project_manage.php
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// Ensure only faculty can access this page
|
| 8 |
+
requireFaculty();
|
| 9 |
+
|
| 10 |
+
// Initialize variables
|
| 11 |
+
$error = '';
|
| 12 |
+
$success = '';
|
| 13 |
+
$domain_tables = getDomainTables($conn);
|
| 14 |
+
|
| 15 |
+
// Check if project was deleted
|
| 16 |
+
if (isset($_GET['deleted']) && $_GET['deleted'] === '1' && isset($_GET['project'])) {
|
| 17 |
+
$success = "Project '" . htmlspecialchars($_GET['project']) . "' has been deleted successfully.";
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
// Handle delete request
|
| 21 |
+
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['domain']) && isset($_GET['id'])) {
|
| 22 |
+
$domainNumber = intval($_GET['domain']);
|
| 23 |
+
$projectId = intval($_GET['id']);
|
| 24 |
+
|
| 25 |
+
// Redirect to the delete confirmation page
|
| 26 |
+
header("Location: project_delete.php?domain=" . urlencode($domainNumber) . "&id=" . urlencode($projectId));
|
| 27 |
+
exit;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// Search and filtering
|
| 31 |
+
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
|
| 32 |
+
$domain_filter = isset($_GET['domain']) ? intval($_GET['domain']) : 0;
|
| 33 |
+
$type_filter = isset($_GET['type']) ? trim($_GET['type']) : '';
|
| 34 |
+
|
| 35 |
+
// Pagination
|
| 36 |
+
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
|
| 37 |
+
$per_page = 10;
|
| 38 |
+
$offset = ($page - 1) * $per_page;
|
| 39 |
+
|
| 40 |
+
// Get all projects across domains
|
| 41 |
+
$projects = [];
|
| 42 |
+
$total_count = 0;
|
| 43 |
+
|
| 44 |
+
foreach ($domain_tables as $domain_id => $domain_table) {
|
| 45 |
+
// Skip if domain filter is set and doesn't match
|
| 46 |
+
if ($domain_filter > 0 && $domain_id != $domain_filter) {
|
| 47 |
+
continue;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
// Get project name field for this domain
|
| 51 |
+
$projectNameField = getProjectNameField($conn, $domain_table);
|
| 52 |
+
|
| 53 |
+
// Build the query
|
| 54 |
+
$query = "SELECT *, '$domain_id' as domain_number FROM $domain_table";
|
| 55 |
+
$where_clauses = [];
|
| 56 |
+
$params = [];
|
| 57 |
+
$types = '';
|
| 58 |
+
|
| 59 |
+
// Add search condition if search term is provided
|
| 60 |
+
if (!empty($search)) {
|
| 61 |
+
$where_clauses[] = "(`$projectNameField` LIKE ? OR `Description` LIKE ?)";
|
| 62 |
+
$search_param = "%$search%";
|
| 63 |
+
$params[] = $search_param;
|
| 64 |
+
$params[] = $search_param;
|
| 65 |
+
$types .= 'ss';
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// Add type filter if provided
|
| 69 |
+
if (!empty($type_filter)) {
|
| 70 |
+
$where_clauses[] = "`H/S` = ?";
|
| 71 |
+
$params[] = $type_filter;
|
| 72 |
+
$types .= 's';
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
// Finalize the query
|
| 76 |
+
if (!empty($where_clauses)) {
|
| 77 |
+
$query .= " WHERE " . implode(' AND ', $where_clauses);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
// First, get the total count for this domain
|
| 81 |
+
$count_query = str_replace("SELECT *, '$domain_id' as domain_number", "SELECT COUNT(*)", $query);
|
| 82 |
+
$count_stmt = $conn->prepare($count_query);
|
| 83 |
+
|
| 84 |
+
if ($count_stmt) {
|
| 85 |
+
if (!empty($params)) {
|
| 86 |
+
$count_stmt->bind_param($types, ...$params);
|
| 87 |
+
}
|
| 88 |
+
$count_stmt->execute();
|
| 89 |
+
$count_result = $count_stmt->get_result();
|
| 90 |
+
$count_row = $count_result->fetch_row();
|
| 91 |
+
$total_count += $count_row[0];
|
| 92 |
+
$count_stmt->close();
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
// Now get the actual projects
|
| 96 |
+
$query .= " ORDER BY Project_ID DESC";
|
| 97 |
+
$stmt = $conn->prepare($query);
|
| 98 |
+
|
| 99 |
+
if ($stmt) {
|
| 100 |
+
if (!empty($params)) {
|
| 101 |
+
$stmt->bind_param($types, ...$params);
|
| 102 |
+
}
|
| 103 |
+
$stmt->execute();
|
| 104 |
+
$result = $stmt->get_result();
|
| 105 |
+
|
| 106 |
+
while ($row = $result->fetch_assoc()) {
|
| 107 |
+
$row['domain_table'] = $domain_table;
|
| 108 |
+
$row['projectNameField'] = $projectNameField;
|
| 109 |
+
$projects[] = $row;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
$stmt->close();
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
// If domain filter is active, we need to adjust pagination
|
| 117 |
+
$total_pages = ceil($total_count / $per_page);
|
| 118 |
+
|
| 119 |
+
// Sort projects by most recent (assuming Project_ID increases with newer projects)
|
| 120 |
+
usort($projects, function($a, $b) {
|
| 121 |
+
return $b['Project_ID'] - $a['Project_ID'];
|
| 122 |
+
});
|
| 123 |
+
|
| 124 |
+
// Apply pagination
|
| 125 |
+
$paginated_projects = array_slice($projects, $offset, $per_page);
|
| 126 |
+
|
| 127 |
+
// Get domain descriptions
|
| 128 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 129 |
+
|
| 130 |
+
// Include header
|
| 131 |
+
include 'includes/header.php';
|
| 132 |
+
?>
|
| 133 |
+
|
| 134 |
+
<div class="row mb-4">
|
| 135 |
+
<div class="col-md-12">
|
| 136 |
+
<nav aria-label="breadcrumb">
|
| 137 |
+
<ol class="breadcrumb">
|
| 138 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 139 |
+
<li class="breadcrumb-item active">Manage Projects</li>
|
| 140 |
+
</ol>
|
| 141 |
+
</nav>
|
| 142 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 143 |
+
<h2><i class="fas fa-tasks me-2"></i> Manage Projects</h2>
|
| 144 |
+
<a href="project_add.php" class="btn btn-primary">
|
| 145 |
+
<i class="fas fa-plus-circle me-1"></i> Add New Project
|
| 146 |
+
</a>
|
| 147 |
+
</div>
|
| 148 |
+
</div>
|
| 149 |
+
</div>
|
| 150 |
+
|
| 151 |
+
<?php if (!empty($success)): ?>
|
| 152 |
+
<div class="alert alert-success">
|
| 153 |
+
<i class="fas fa-check-circle me-2"></i> <?php echo $success; ?>
|
| 154 |
+
</div>
|
| 155 |
+
<?php endif; ?>
|
| 156 |
+
|
| 157 |
+
<?php if (!empty($error)): ?>
|
| 158 |
+
<div class="alert alert-danger">
|
| 159 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 160 |
+
</div>
|
| 161 |
+
<?php endif; ?>
|
| 162 |
+
|
| 163 |
+
<div class="card shadow-sm mb-4">
|
| 164 |
+
<div class="card-header bg-light">
|
| 165 |
+
<h5 class="mb-0"><i class="fas fa-filter me-2"></i> Search and Filter</h5>
|
| 166 |
+
</div>
|
| 167 |
+
<div class="card-body">
|
| 168 |
+
<form method="get" action="project_manage.php" class="row g-3">
|
| 169 |
+
<div class="col-md-4">
|
| 170 |
+
<label for="search" class="form-label">Search</label>
|
| 171 |
+
<div class="input-group">
|
| 172 |
+
<input type="text" class="form-control" id="search" name="search"
|
| 173 |
+
placeholder="Search by name or description" value="<?php echo htmlspecialchars($search); ?>">
|
| 174 |
+
<button class="btn btn-outline-secondary" type="submit">
|
| 175 |
+
<i class="fas fa-search"></i>
|
| 176 |
+
</button>
|
| 177 |
+
</div>
|
| 178 |
+
</div>
|
| 179 |
+
|
| 180 |
+
<div class="col-md-4">
|
| 181 |
+
<label for="domain" class="form-label">Domain</label>
|
| 182 |
+
<select class="form-select" id="domain" name="domain">
|
| 183 |
+
<option value="0">All Domains</option>
|
| 184 |
+
<?php foreach ($domain_tables as $id => $table): ?>
|
| 185 |
+
<?php $desc = isset($domainDescriptions[$id]) ? $domainDescriptions[$id] : "Domain $id"; ?>
|
| 186 |
+
<option value="<?php echo $id; ?>" <?php echo ($domain_filter == $id) ? 'selected' : ''; ?>>
|
| 187 |
+
Domain <?php echo $id; ?>: <?php echo htmlspecialchars($desc); ?>
|
| 188 |
+
</option>
|
| 189 |
+
<?php endforeach; ?>
|
| 190 |
+
</select>
|
| 191 |
+
</div>
|
| 192 |
+
|
| 193 |
+
<div class="col-md-3">
|
| 194 |
+
<label for="type" class="form-label">Project Type</label>
|
| 195 |
+
<select class="form-select" id="type" name="type">
|
| 196 |
+
<option value="">All Types</option>
|
| 197 |
+
<option value="Hardware" <?php echo ($type_filter === 'Hardware') ? 'selected' : ''; ?>>Hardware</option>
|
| 198 |
+
<option value="Software" <?php echo ($type_filter === 'Software') ? 'selected' : ''; ?>>Software</option>
|
| 199 |
+
</select>
|
| 200 |
+
</div>
|
| 201 |
+
|
| 202 |
+
<div class="col-md-1 d-flex align-items-end">
|
| 203 |
+
<?php if (!empty($search) || $domain_filter > 0 || !empty($type_filter)): ?>
|
| 204 |
+
<a href="project_manage.php" class="btn btn-outline-secondary">
|
| 205 |
+
<i class="fas fa-times"></i> Clear
|
| 206 |
+
</a>
|
| 207 |
+
<?php endif; ?>
|
| 208 |
+
</div>
|
| 209 |
+
</form>
|
| 210 |
+
</div>
|
| 211 |
+
</div>
|
| 212 |
+
|
| 213 |
+
<div class="card shadow-sm">
|
| 214 |
+
<div class="card-header bg-light d-flex justify-content-between align-items-center">
|
| 215 |
+
<h5 class="mb-0"><i class="fas fa-clipboard-list me-2"></i> Projects</h5>
|
| 216 |
+
<span class="badge bg-primary rounded-pill"><?php echo $total_count; ?> Projects</span>
|
| 217 |
+
</div>
|
| 218 |
+
<div class="card-body">
|
| 219 |
+
<?php if (empty($paginated_projects)): ?>
|
| 220 |
+
<div class="alert alert-info">
|
| 221 |
+
<i class="fas fa-info-circle me-2"></i> No projects found matching your criteria. Try different search parameters or <a href="project_add.php" class="alert-link">add a new project</a>.
|
| 222 |
+
</div>
|
| 223 |
+
<?php else: ?>
|
| 224 |
+
<div class="table-responsive">
|
| 225 |
+
<table class="table table-hover">
|
| 226 |
+
<thead class="table-light">
|
| 227 |
+
<tr>
|
| 228 |
+
<th>ID</th>
|
| 229 |
+
<th>Domain</th>
|
| 230 |
+
<th>Project Name</th>
|
| 231 |
+
<th>Type</th>
|
| 232 |
+
<th>Actions</th>
|
| 233 |
+
</tr>
|
| 234 |
+
</thead>
|
| 235 |
+
<tbody>
|
| 236 |
+
<?php foreach ($paginated_projects as $project): ?>
|
| 237 |
+
<?php
|
| 238 |
+
$domain_id = $project['domain_number'];
|
| 239 |
+
$projectName = $project[$project['projectNameField']];
|
| 240 |
+
$domainDesc = isset($domainDescriptions[$domain_id]) ? $domainDescriptions[$domain_id] : "Domain $domain_id";
|
| 241 |
+
?>
|
| 242 |
+
<tr>
|
| 243 |
+
<td><?php echo $project['Project_ID']; ?></td>
|
| 244 |
+
<td>
|
| 245 |
+
<span class="badge bg-secondary">Domain <?php echo $domain_id; ?></span>
|
| 246 |
+
<small class="d-block text-muted"><?php echo htmlspecialchars($domainDesc); ?></small>
|
| 247 |
+
</td>
|
| 248 |
+
<td><?php echo htmlspecialchars($projectName); ?></td>
|
| 249 |
+
<td>
|
| 250 |
+
<?php if (isset($project['H/S'])): ?>
|
| 251 |
+
<?php if ($project['H/S'] === 'Hardware'): ?>
|
| 252 |
+
<span class="badge bg-danger">Hardware</span>
|
| 253 |
+
<?php elseif ($project['H/S'] === 'Software'): ?>
|
| 254 |
+
<span class="badge bg-success">Software</span>
|
| 255 |
+
<?php else: ?>
|
| 256 |
+
<span class="badge bg-secondary"><?php echo htmlspecialchars($project['H/S']); ?></span>
|
| 257 |
+
<?php endif; ?>
|
| 258 |
+
<?php else: ?>
|
| 259 |
+
<span class="badge bg-secondary">N/A</span>
|
| 260 |
+
<?php endif; ?>
|
| 261 |
+
</td>
|
| 262 |
+
<td>
|
| 263 |
+
<div class="btn-group btn-group-sm" role="group">
|
| 264 |
+
<a href="project_details.php?domain=<?php echo urlencode($domain_id); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-outline-primary" title="View Project">
|
| 265 |
+
<i class="fas fa-eye"></i>
|
| 266 |
+
</a>
|
| 267 |
+
<a href="project_edit.php?domain=<?php echo urlencode($domain_id); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-outline-success" title="Edit Project">
|
| 268 |
+
<i class="fas fa-edit"></i>
|
| 269 |
+
</a>
|
| 270 |
+
<a href="project_delete.php?domain=<?php echo urlencode($domain_id); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-outline-danger" title="Delete Project">
|
| 271 |
+
<i class="fas fa-trash-alt"></i>
|
| 272 |
+
</a>
|
| 273 |
+
</div>
|
| 274 |
+
</td>
|
| 275 |
+
</tr>
|
| 276 |
+
<?php endforeach; ?>
|
| 277 |
+
</tbody>
|
| 278 |
+
</table>
|
| 279 |
+
</div>
|
| 280 |
+
|
| 281 |
+
<?php if ($total_pages > 1): ?>
|
| 282 |
+
<nav aria-label="Page navigation" class="mt-4">
|
| 283 |
+
<ul class="pagination justify-content-center">
|
| 284 |
+
<li class="page-item <?php echo ($page <= 1) ? 'disabled' : ''; ?>">
|
| 285 |
+
<a class="page-link" href="<?php echo ($page <= 1) ? '#' : "project_manage.php?page=" . ($page - 1) . "&search=" . urlencode($search) . "&domain=" . urlencode($domain_filter) . "&type=" . urlencode($type_filter); ?>">
|
| 286 |
+
<i class="fas fa-chevron-left"></i> Previous
|
| 287 |
+
</a>
|
| 288 |
+
</li>
|
| 289 |
+
|
| 290 |
+
<?php for ($i = max(1, $page - 2); $i <= min($total_pages, $page + 2); $i++): ?>
|
| 291 |
+
<li class="page-item <?php echo ($i == $page) ? 'active' : ''; ?>">
|
| 292 |
+
<a class="page-link" href="project_manage.php?page=<?php echo $i; ?>&search=<?php echo urlencode($search); ?>&domain=<?php echo urlencode($domain_filter); ?>&type=<?php echo urlencode($type_filter); ?>">
|
| 293 |
+
<?php echo $i; ?>
|
| 294 |
+
</a>
|
| 295 |
+
</li>
|
| 296 |
+
<?php endfor; ?>
|
| 297 |
+
|
| 298 |
+
<li class="page-item <?php echo ($page >= $total_pages) ? 'disabled' : ''; ?>">
|
| 299 |
+
<a class="page-link" href="<?php echo ($page >= $total_pages) ? '#' : "project_manage.php?page=" . ($page + 1) . "&search=" . urlencode($search) . "&domain=" . urlencode($domain_filter) . "&type=" . urlencode($type_filter); ?>">
|
| 300 |
+
Next <i class="fas fa-chevron-right"></i>
|
| 301 |
+
</a>
|
| 302 |
+
</li>
|
| 303 |
+
</ul>
|
| 304 |
+
</nav>
|
| 305 |
+
<?php endif; ?>
|
| 306 |
+
<?php endif; ?>
|
| 307 |
+
</div>
|
| 308 |
+
</div>
|
| 309 |
+
|
| 310 |
+
<?php
|
| 311 |
+
// Include footer
|
| 312 |
+
include 'includes/footer.php';
|
| 313 |
+
|
| 314 |
+
// Close connection
|
| 315 |
+
$conn->close();
|
| 316 |
+
?>
|
register.php
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
|
| 5 |
+
// Start session if not already started
|
| 6 |
+
if (session_status() === PHP_SESSION_NONE) {
|
| 7 |
+
session_start();
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
// Check if user is already logged in
|
| 11 |
+
if (isset($_SESSION['user_id'])) {
|
| 12 |
+
header('Location: index.php');
|
| 13 |
+
exit;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
$error = '';
|
| 17 |
+
$success = '';
|
| 18 |
+
|
| 19 |
+
// Process registration form
|
| 20 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 21 |
+
// Validate inputs
|
| 22 |
+
$username = $conn->real_escape_string(trim($_POST['username']));
|
| 23 |
+
$email = $conn->real_escape_string(trim($_POST['email']));
|
| 24 |
+
$password = trim($_POST['password']);
|
| 25 |
+
$confirm_password = trim($_POST['confirm_password']);
|
| 26 |
+
$user_type = $conn->real_escape_string(trim($_POST['user_type']));
|
| 27 |
+
|
| 28 |
+
// Validation
|
| 29 |
+
if (empty($username) || empty($email) || empty($password) || empty($confirm_password) || empty($user_type)) {
|
| 30 |
+
$error = "All fields are required.";
|
| 31 |
+
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
| 32 |
+
$error = "Please enter a valid email address.";
|
| 33 |
+
} elseif (strlen($password) < 6) {
|
| 34 |
+
$error = "Password must be at least 6 characters long.";
|
| 35 |
+
} elseif ($password !== $confirm_password) {
|
| 36 |
+
$error = "Passwords do not match.";
|
| 37 |
+
} elseif ($user_type !== 'student' && $user_type !== 'faculty') {
|
| 38 |
+
$error = "Invalid user type.";
|
| 39 |
+
} else {
|
| 40 |
+
// Check if username already exists
|
| 41 |
+
$check_query = "SELECT * FROM users WHERE username = ? OR email = ?";
|
| 42 |
+
$check_stmt = $conn->prepare($check_query);
|
| 43 |
+
$check_stmt->bind_param("ss", $username, $email);
|
| 44 |
+
$check_stmt->execute();
|
| 45 |
+
$check_result = $check_stmt->get_result();
|
| 46 |
+
|
| 47 |
+
if ($check_result->num_rows > 0) {
|
| 48 |
+
$user = $check_result->fetch_assoc();
|
| 49 |
+
if ($user['username'] === $username) {
|
| 50 |
+
$error = "Username already taken. Please choose another.";
|
| 51 |
+
} else {
|
| 52 |
+
$error = "Email already registered. Please use another email or login.";
|
| 53 |
+
}
|
| 54 |
+
} else {
|
| 55 |
+
// Check if users table exists, create it if not
|
| 56 |
+
$table_check = "SHOW TABLES LIKE 'users'";
|
| 57 |
+
$table_exists = $conn->query($table_check)->num_rows > 0;
|
| 58 |
+
|
| 59 |
+
if (!$table_exists) {
|
| 60 |
+
$create_table = "CREATE TABLE users (
|
| 61 |
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
| 62 |
+
username VARCHAR(50) NOT NULL UNIQUE,
|
| 63 |
+
email VARCHAR(100) NOT NULL UNIQUE,
|
| 64 |
+
password VARCHAR(255) NOT NULL,
|
| 65 |
+
user_type ENUM('student', 'faculty') NOT NULL,
|
| 66 |
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 67 |
+
last_login TIMESTAMP NULL,
|
| 68 |
+
status ENUM('active', 'inactive') DEFAULT 'active'
|
| 69 |
+
)";
|
| 70 |
+
|
| 71 |
+
if (!$conn->query($create_table)) {
|
| 72 |
+
$error = "Error creating user table: " . $conn->error;
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
if (empty($error)) {
|
| 77 |
+
// Hash password
|
| 78 |
+
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
| 79 |
+
|
| 80 |
+
// Insert new user
|
| 81 |
+
$insert_query = "INSERT INTO users (username, email, password, user_type) VALUES (?, ?, ?, ?)";
|
| 82 |
+
$insert_stmt = $conn->prepare($insert_query);
|
| 83 |
+
$insert_stmt->bind_param("ssss", $username, $email, $hashed_password, $user_type);
|
| 84 |
+
|
| 85 |
+
if ($insert_stmt->execute()) {
|
| 86 |
+
// Registration successful
|
| 87 |
+
$_SESSION['success_message'] = "Registration successful! Please login with your credentials.";
|
| 88 |
+
header('Location: login.php');
|
| 89 |
+
exit;
|
| 90 |
+
} else {
|
| 91 |
+
$error = "Registration failed: " . $conn->error;
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
// Include header
|
| 99 |
+
include 'includes/header.php';
|
| 100 |
+
?>
|
| 101 |
+
|
| 102 |
+
<div class="row">
|
| 103 |
+
<div class="col-md-12 mb-4 text-center">
|
| 104 |
+
<h2>Create a New Account</h2>
|
| 105 |
+
<p class="lead">Join the Domain Management System</p>
|
| 106 |
+
</div>
|
| 107 |
+
</div>
|
| 108 |
+
|
| 109 |
+
<div class="row">
|
| 110 |
+
<div class="col-md-6 offset-md-3">
|
| 111 |
+
<div class="auth-form">
|
| 112 |
+
<?php if (!empty($error)): ?>
|
| 113 |
+
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
| 114 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 115 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 116 |
+
</div>
|
| 117 |
+
<?php endif; ?>
|
| 118 |
+
|
| 119 |
+
<div class="card shadow">
|
| 120 |
+
<div class="card-header bg-primary text-white text-center">
|
| 121 |
+
<h4 class="mb-0"><i class="fas fa-user-plus me-2"></i> Register</h4>
|
| 122 |
+
</div>
|
| 123 |
+
<div class="card-body">
|
| 124 |
+
<form method="POST" action="register.php" class="needs-validation" novalidate>
|
| 125 |
+
<div class="mb-3">
|
| 126 |
+
<label for="user_type" class="form-label">Register As</label>
|
| 127 |
+
<select class="form-select" id="user_type" name="user_type" required>
|
| 128 |
+
<option value="" selected disabled>Select user type</option>
|
| 129 |
+
<option value="student">Student</option>
|
| 130 |
+
<option value="faculty">Faculty</option>
|
| 131 |
+
</select>
|
| 132 |
+
<div class="invalid-feedback">
|
| 133 |
+
Please select a user type.
|
| 134 |
+
</div>
|
| 135 |
+
</div>
|
| 136 |
+
<div class="mb-3">
|
| 137 |
+
<label for="username" class="form-label">Username</label>
|
| 138 |
+
<div class="input-group">
|
| 139 |
+
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
| 140 |
+
<input type="text" class="form-control" id="username" name="username" placeholder="Choose a username" required>
|
| 141 |
+
</div>
|
| 142 |
+
<div class="invalid-feedback">
|
| 143 |
+
Please choose a username.
|
| 144 |
+
</div>
|
| 145 |
+
</div>
|
| 146 |
+
<div class="mb-3">
|
| 147 |
+
<label for="email" class="form-label">Email</label>
|
| 148 |
+
<div class="input-group">
|
| 149 |
+
<span class="input-group-text"><i class="fas fa-envelope"></i></span>
|
| 150 |
+
<input type="email" class="form-control" id="email" name="email" placeholder="Enter your email" required>
|
| 151 |
+
</div>
|
| 152 |
+
<div class="invalid-feedback">
|
| 153 |
+
Please enter a valid email address.
|
| 154 |
+
</div>
|
| 155 |
+
</div>
|
| 156 |
+
<div class="mb-3">
|
| 157 |
+
<label for="password" class="form-label">Password</label>
|
| 158 |
+
<div class="input-group">
|
| 159 |
+
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
| 160 |
+
<input type="password" class="form-control" id="password" name="password" placeholder="Choose a password" required minlength="6">
|
| 161 |
+
<button class="btn btn-outline-secondary toggle-password" type="button" data-target="#password">
|
| 162 |
+
<i class="fas fa-eye"></i>
|
| 163 |
+
</button>
|
| 164 |
+
</div>
|
| 165 |
+
<div class="form-text">Password must be at least 6 characters long.</div>
|
| 166 |
+
<div class="invalid-feedback">
|
| 167 |
+
Please enter a password (minimum 6 characters).
|
| 168 |
+
</div>
|
| 169 |
+
</div>
|
| 170 |
+
<div class="mb-4">
|
| 171 |
+
<label for="confirm_password" class="form-label">Confirm Password</label>
|
| 172 |
+
<div class="input-group">
|
| 173 |
+
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
| 174 |
+
<input type="password" class="form-control" id="confirm_password" name="confirm_password" placeholder="Confirm your password" required>
|
| 175 |
+
<button class="btn btn-outline-secondary toggle-password" type="button" data-target="#confirm_password">
|
| 176 |
+
<i class="fas fa-eye"></i>
|
| 177 |
+
</button>
|
| 178 |
+
</div>
|
| 179 |
+
<div class="invalid-feedback">
|
| 180 |
+
Please confirm your password.
|
| 181 |
+
</div>
|
| 182 |
+
</div>
|
| 183 |
+
<div class="d-grid">
|
| 184 |
+
<button type="submit" class="btn btn-primary btn-lg">
|
| 185 |
+
<i class="fas fa-user-plus me-2"></i> Create Account
|
| 186 |
+
</button>
|
| 187 |
+
</div>
|
| 188 |
+
</form>
|
| 189 |
+
</div>
|
| 190 |
+
<div class="card-footer text-center">
|
| 191 |
+
<p class="mb-0">Already have an account? <a href="login.php">Login here</a></p>
|
| 192 |
+
</div>
|
| 193 |
+
</div>
|
| 194 |
+
</div>
|
| 195 |
+
</div>
|
| 196 |
+
</div>
|
| 197 |
+
|
| 198 |
+
<?php
|
| 199 |
+
// Include footer
|
| 200 |
+
include 'includes/footer.php';
|
| 201 |
+
|
| 202 |
+
// Close connection
|
| 203 |
+
$conn->close();
|
| 204 |
+
?>
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
flask==2.0.1
|
| 2 |
+
mysql-connector-python==8.0.26
|
| 3 |
+
python-dotenv==0.19.0
|
| 4 |
+
gunicorn==20.1.0
|
runtime.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
python-3.9.18
|
script.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 2 |
+
// Initialize tooltips
|
| 3 |
+
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
| 4 |
+
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
| 5 |
+
return new bootstrap.Tooltip(tooltipTriggerEl);
|
| 6 |
+
});
|
| 7 |
+
|
| 8 |
+
// Add fade-in animation to main content
|
| 9 |
+
document.querySelector('main').classList.add('fade-in');
|
| 10 |
+
|
| 11 |
+
// Password visibility toggle
|
| 12 |
+
const togglePasswordButtons = document.querySelectorAll('.toggle-password');
|
| 13 |
+
if (togglePasswordButtons) {
|
| 14 |
+
togglePasswordButtons.forEach(button => {
|
| 15 |
+
button.addEventListener('click', function() {
|
| 16 |
+
const passwordInput = document.querySelector(this.getAttribute('data-target'));
|
| 17 |
+
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
|
| 18 |
+
passwordInput.setAttribute('type', type);
|
| 19 |
+
|
| 20 |
+
// Toggle icon
|
| 21 |
+
this.querySelector('i').classList.toggle('fa-eye');
|
| 22 |
+
this.querySelector('i').classList.toggle('fa-eye-slash');
|
| 23 |
+
});
|
| 24 |
+
});
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
// Confirm delete prompts
|
| 28 |
+
const deleteButtons = document.querySelectorAll('.btn-delete');
|
| 29 |
+
if (deleteButtons) {
|
| 30 |
+
deleteButtons.forEach(button => {
|
| 31 |
+
button.addEventListener('click', function(e) {
|
| 32 |
+
if (!confirm('Are you sure you want to delete this item? This action cannot be undone.')) {
|
| 33 |
+
e.preventDefault();
|
| 34 |
+
}
|
| 35 |
+
});
|
| 36 |
+
});
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
// Table row highlight on hover
|
| 40 |
+
const tableRows = document.querySelectorAll('tbody tr');
|
| 41 |
+
if (tableRows) {
|
| 42 |
+
tableRows.forEach(row => {
|
| 43 |
+
row.addEventListener('mouseenter', function() {
|
| 44 |
+
this.classList.add('highlight');
|
| 45 |
+
});
|
| 46 |
+
row.addEventListener('mouseleave', function() {
|
| 47 |
+
this.classList.remove('highlight');
|
| 48 |
+
});
|
| 49 |
+
});
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
// Search input focus effect
|
| 53 |
+
const searchInputs = document.querySelectorAll('input[type="search"], input[name="search"]');
|
| 54 |
+
if (searchInputs) {
|
| 55 |
+
searchInputs.forEach(input => {
|
| 56 |
+
input.addEventListener('focus', function() {
|
| 57 |
+
this.parentElement.classList.add('search-focus');
|
| 58 |
+
});
|
| 59 |
+
input.addEventListener('blur', function() {
|
| 60 |
+
this.parentElement.classList.remove('search-focus');
|
| 61 |
+
});
|
| 62 |
+
});
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// Form validation
|
| 66 |
+
const forms = document.querySelectorAll('.needs-validation');
|
| 67 |
+
if (forms) {
|
| 68 |
+
Array.from(forms).forEach(form => {
|
| 69 |
+
form.addEventListener('submit', event => {
|
| 70 |
+
if (!form.checkValidity()) {
|
| 71 |
+
event.preventDefault();
|
| 72 |
+
event.stopPropagation();
|
| 73 |
+
}
|
| 74 |
+
form.classList.add('was-validated');
|
| 75 |
+
}, false);
|
| 76 |
+
});
|
| 77 |
+
}
|
| 78 |
+
});
|
student_projects.php
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/domain_utils.php';
|
| 5 |
+
require_once 'includes/auth_check.php';
|
| 6 |
+
|
| 7 |
+
// This page is for faculty only
|
| 8 |
+
requireFaculty();
|
| 9 |
+
|
| 10 |
+
// Check if student ID is provided
|
| 11 |
+
if (!isset($_GET['id'])) {
|
| 12 |
+
header("Location: students.php");
|
| 13 |
+
exit;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
$studentId = $_GET['id'];
|
| 17 |
+
$error = '';
|
| 18 |
+
$studentData = null;
|
| 19 |
+
$studentProjects = [];
|
| 20 |
+
|
| 21 |
+
// Check if students_info table exists
|
| 22 |
+
$tableCheckQuery = "SHOW TABLES LIKE 'students_info'";
|
| 23 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 24 |
+
|
| 25 |
+
if ($tableExists) {
|
| 26 |
+
// Get student data structure to find the ID field
|
| 27 |
+
$columnsQuery = "SHOW COLUMNS FROM students_info";
|
| 28 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 29 |
+
$studentIdField = null;
|
| 30 |
+
$studentNameFields = [];
|
| 31 |
+
|
| 32 |
+
// Find student ID and name fields
|
| 33 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 34 |
+
if (preg_match('/(student|stud|roll)[\s_-]?(id|number|no)/i', $column['Field'])) {
|
| 35 |
+
$studentIdField = $column['Field'];
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
if (preg_match('/(student|stud)[\s_-]?(name)/i', $column['Field']) ||
|
| 39 |
+
preg_match('/(first|last|full)[\s_-]?(name)/i', $column['Field'])) {
|
| 40 |
+
$studentNameFields[] = $column['Field'];
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
if ($studentIdField) {
|
| 45 |
+
// Fetch student data
|
| 46 |
+
$studentQuery = "SELECT * FROM students_info WHERE $studentIdField = ?";
|
| 47 |
+
$stmt = $conn->prepare($studentQuery);
|
| 48 |
+
$stmt->bind_param('s', $studentId);
|
| 49 |
+
$stmt->execute();
|
| 50 |
+
$result = $stmt->get_result();
|
| 51 |
+
|
| 52 |
+
if ($result && $result->num_rows > 0) {
|
| 53 |
+
$studentData = $result->fetch_assoc();
|
| 54 |
+
|
| 55 |
+
// Find project field in student data
|
| 56 |
+
$projectIdField = null;
|
| 57 |
+
$domainIdField = null;
|
| 58 |
+
|
| 59 |
+
foreach ($studentData as $field => $value) {
|
| 60 |
+
if (preg_match('/(project)[\s_-]?(id)/i', $field)) {
|
| 61 |
+
$projectIdField = $field;
|
| 62 |
+
}
|
| 63 |
+
if (preg_match('/(domain)[\s_-]?(id)/i', $field)) {
|
| 64 |
+
$domainIdField = $field;
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// If specific project field found, get project details
|
| 69 |
+
if ($projectIdField && !empty($studentData[$projectIdField])) {
|
| 70 |
+
$projectId = $studentData[$projectIdField];
|
| 71 |
+
|
| 72 |
+
// If domain field is found, use it to find the right domain table
|
| 73 |
+
if ($domainIdField && !empty($studentData[$domainIdField])) {
|
| 74 |
+
$domainId = $studentData[$domainIdField];
|
| 75 |
+
// Extract domain number if format is like 'D-1'
|
| 76 |
+
if (preg_match('/D-(\d+)/', $domainId, $matches)) {
|
| 77 |
+
$domainNumber = $matches[1];
|
| 78 |
+
$domainTable = "domain_" . $domainNumber;
|
| 79 |
+
|
| 80 |
+
// Check if table exists
|
| 81 |
+
$tableCheckQuery = "SHOW TABLES LIKE '$domainTable'";
|
| 82 |
+
if ($conn->query($tableCheckQuery)->num_rows > 0) {
|
| 83 |
+
// Get project name field for this domain
|
| 84 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 85 |
+
|
| 86 |
+
// Fetch project details
|
| 87 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE Project_ID = ?";
|
| 88 |
+
$stmt = $conn->prepare($projectQuery);
|
| 89 |
+
$stmt->bind_param('i', $projectId);
|
| 90 |
+
$stmt->execute();
|
| 91 |
+
$projectResult = $stmt->get_result();
|
| 92 |
+
|
| 93 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 94 |
+
$project = $projectResult->fetch_assoc();
|
| 95 |
+
$project['project_name_field'] = $projectNameField;
|
| 96 |
+
$studentProjects[] = $project;
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
}
|
| 100 |
+
} else {
|
| 101 |
+
// If no domain field, search all domain tables
|
| 102 |
+
$domainTables = getDomainTables($conn);
|
| 103 |
+
|
| 104 |
+
foreach ($domainTables as $domainTable) {
|
| 105 |
+
$domainNumber = str_replace('domain_', '', $domainTable);
|
| 106 |
+
|
| 107 |
+
// Get project name field for this domain
|
| 108 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 109 |
+
|
| 110 |
+
// Check for project in this domain
|
| 111 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE Project_ID = ?";
|
| 112 |
+
$stmt = $conn->prepare($projectQuery);
|
| 113 |
+
$stmt->bind_param('i', $projectId);
|
| 114 |
+
$stmt->execute();
|
| 115 |
+
$projectResult = $stmt->get_result();
|
| 116 |
+
|
| 117 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 118 |
+
$project = $projectResult->fetch_assoc();
|
| 119 |
+
$project['project_name_field'] = $projectNameField;
|
| 120 |
+
$studentProjects[] = $project;
|
| 121 |
+
break; // Found the project, no need to search other tables
|
| 122 |
+
}
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
} else {
|
| 126 |
+
// If no specific project field or project ID is empty,
|
| 127 |
+
// try to find projects by searching for the student ID in all domain tables
|
| 128 |
+
$domainTables = getDomainTables($conn);
|
| 129 |
+
|
| 130 |
+
foreach ($domainTables as $domainTable) {
|
| 131 |
+
$domainNumber = str_replace('domain_', '', $domainTable);
|
| 132 |
+
|
| 133 |
+
// Get columns of the domain table
|
| 134 |
+
$columnsQuery = "SHOW COLUMNS FROM $domainTable";
|
| 135 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 136 |
+
$studentColumns = [];
|
| 137 |
+
|
| 138 |
+
// Find columns that might contain student IDs
|
| 139 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 140 |
+
if (preg_match('/(student|stud|member)[\s_-]?(id|ids|no|number)/i', $column['Field'])) {
|
| 141 |
+
$studentColumns[] = $column['Field'];
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// Get project name field for this domain
|
| 146 |
+
$projectNameField = getProjectNameField($conn, $domainTable);
|
| 147 |
+
|
| 148 |
+
// Check each potential student column
|
| 149 |
+
foreach ($studentColumns as $studentColumn) {
|
| 150 |
+
// Try exact match
|
| 151 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE $studentColumn = ?";
|
| 152 |
+
$stmt = $conn->prepare($projectQuery);
|
| 153 |
+
$stmt->bind_param('s', $studentId);
|
| 154 |
+
$stmt->execute();
|
| 155 |
+
$projectResult = $stmt->get_result();
|
| 156 |
+
|
| 157 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 158 |
+
while ($project = $projectResult->fetch_assoc()) {
|
| 159 |
+
$project['project_name_field'] = $projectNameField;
|
| 160 |
+
$studentProjects[] = $project;
|
| 161 |
+
}
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
// Try LIKE match (if the column might contain multiple IDs)
|
| 165 |
+
$projectQuery = "SELECT *, '$domainNumber' as domain_number FROM $domainTable WHERE $studentColumn LIKE ?";
|
| 166 |
+
$likeParam = "%$studentId%";
|
| 167 |
+
$stmt = $conn->prepare($projectQuery);
|
| 168 |
+
$stmt->bind_param('s', $likeParam);
|
| 169 |
+
$stmt->execute();
|
| 170 |
+
$projectResult = $stmt->get_result();
|
| 171 |
+
|
| 172 |
+
if ($projectResult && $projectResult->num_rows > 0) {
|
| 173 |
+
while ($project = $projectResult->fetch_assoc()) {
|
| 174 |
+
// Check if this project is already added
|
| 175 |
+
$duplicate = false;
|
| 176 |
+
foreach ($studentProjects as $existingProject) {
|
| 177 |
+
if ($existingProject['Project_ID'] == $project['Project_ID'] &&
|
| 178 |
+
$existingProject['domain_number'] == $project['domain_number']) {
|
| 179 |
+
$duplicate = true;
|
| 180 |
+
break;
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
if (!$duplicate) {
|
| 185 |
+
$project['project_name_field'] = $projectNameField;
|
| 186 |
+
$studentProjects[] = $project;
|
| 187 |
+
}
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
}
|
| 193 |
+
} else {
|
| 194 |
+
$error = "Student with ID '$studentId' not found.";
|
| 195 |
+
}
|
| 196 |
+
} else {
|
| 197 |
+
$error = "Could not determine student ID field in the database.";
|
| 198 |
+
}
|
| 199 |
+
} else {
|
| 200 |
+
$error = "Student information table not found in the database.";
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
// Get domain descriptions for displaying domain names
|
| 204 |
+
$domainDescriptions = getDomainDescriptions($conn);
|
| 205 |
+
|
| 206 |
+
// Include header
|
| 207 |
+
include 'includes/header.php';
|
| 208 |
+
|
| 209 |
+
// Determine student name to display
|
| 210 |
+
$studentName = "Student";
|
| 211 |
+
if ($studentData) {
|
| 212 |
+
foreach ($studentNameFields as $field) {
|
| 213 |
+
if (!empty($studentData[$field])) {
|
| 214 |
+
$studentName = $studentData[$field];
|
| 215 |
+
break;
|
| 216 |
+
}
|
| 217 |
+
}
|
| 218 |
+
}
|
| 219 |
+
?>
|
| 220 |
+
|
| 221 |
+
<div class="row mb-4">
|
| 222 |
+
<div class="col-md-12">
|
| 223 |
+
<nav aria-label="breadcrumb">
|
| 224 |
+
<ol class="breadcrumb">
|
| 225 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 226 |
+
<li class="breadcrumb-item"><a href="students.php">Students</a></li>
|
| 227 |
+
<li class="breadcrumb-item active"><?php echo htmlspecialchars($studentName); ?>'s Projects</li>
|
| 228 |
+
</ol>
|
| 229 |
+
</nav>
|
| 230 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 231 |
+
<h2><i class="fas fa-project-diagram me-2"></i> Projects for <?php echo htmlspecialchars($studentName); ?></h2>
|
| 232 |
+
</div>
|
| 233 |
+
</div>
|
| 234 |
+
</div>
|
| 235 |
+
|
| 236 |
+
<?php if (!empty($error)): ?>
|
| 237 |
+
<div class="alert alert-danger">
|
| 238 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 239 |
+
</div>
|
| 240 |
+
<?php endif; ?>
|
| 241 |
+
|
| 242 |
+
<?php if ($studentData): ?>
|
| 243 |
+
<div class="row mb-4">
|
| 244 |
+
<div class="col-md-12">
|
| 245 |
+
<div class="card shadow-sm">
|
| 246 |
+
<div class="card-header bg-info text-white">
|
| 247 |
+
<h5 class="mb-0"><i class="fas fa-user me-2"></i> Student Information</h5>
|
| 248 |
+
</div>
|
| 249 |
+
<div class="card-body">
|
| 250 |
+
<div class="row">
|
| 251 |
+
<?php foreach ($studentData as $field => $value): ?>
|
| 252 |
+
<div class="col-md-4 mb-3">
|
| 253 |
+
<div class="fw-bold"><?php echo htmlspecialchars($field); ?>:</div>
|
| 254 |
+
<div><?php echo htmlspecialchars($value); ?></div>
|
| 255 |
+
</div>
|
| 256 |
+
<?php endforeach; ?>
|
| 257 |
+
</div>
|
| 258 |
+
</div>
|
| 259 |
+
</div>
|
| 260 |
+
</div>
|
| 261 |
+
</div>
|
| 262 |
+
<?php endif; ?>
|
| 263 |
+
|
| 264 |
+
<div class="row">
|
| 265 |
+
<div class="col-md-12">
|
| 266 |
+
<div class="card shadow-sm">
|
| 267 |
+
<div class="card-header bg-primary text-white">
|
| 268 |
+
<h5 class="mb-0"><i class="fas fa-list me-2"></i> Project List</h5>
|
| 269 |
+
</div>
|
| 270 |
+
<div class="card-body">
|
| 271 |
+
<?php if (count($studentProjects) > 0): ?>
|
| 272 |
+
<div class="table-responsive">
|
| 273 |
+
<table class="table table-striped table-hover">
|
| 274 |
+
<thead class="table-light">
|
| 275 |
+
<tr>
|
| 276 |
+
<th>Project ID</th>
|
| 277 |
+
<th>Project Name</th>
|
| 278 |
+
<th>Type</th>
|
| 279 |
+
<th>Domain</th>
|
| 280 |
+
<th>Actions</th>
|
| 281 |
+
</tr>
|
| 282 |
+
</thead>
|
| 283 |
+
<tbody>
|
| 284 |
+
<?php foreach ($studentProjects as $project):
|
| 285 |
+
$domainNumber = $project['domain_number'];
|
| 286 |
+
$domainDesc = isset($domainDescriptions[$domainNumber]) ? $domainDescriptions[$domainNumber] : 'Domain ' . $domainNumber;
|
| 287 |
+
$projectName = isset($project[$project['project_name_field']]) ? $project[$project['project_name_field']] : 'Project ' . $project['Project_ID'];
|
| 288 |
+
?>
|
| 289 |
+
<tr>
|
| 290 |
+
<td><?php echo htmlspecialchars($project['Project_ID']); ?></td>
|
| 291 |
+
<td><?php echo htmlspecialchars($projectName); ?></td>
|
| 292 |
+
<td>
|
| 293 |
+
<?php if (isset($project['H/S'])): ?>
|
| 294 |
+
<span class="badge bg-<?php echo strtolower($project['H/S']) === 'h' ? 'warning' : 'info'; ?>">
|
| 295 |
+
<?php echo strtolower($project['H/S']) === 'h' ? 'Hardware' : 'Software'; ?>
|
| 296 |
+
</span>
|
| 297 |
+
<?php else: ?>
|
| 298 |
+
<span class="badge bg-secondary">Not specified</span>
|
| 299 |
+
<?php endif; ?>
|
| 300 |
+
</td>
|
| 301 |
+
<td>Domain <?php echo htmlspecialchars($domainNumber); ?>: <?php echo htmlspecialchars($domainDesc); ?></td>
|
| 302 |
+
<td>
|
| 303 |
+
<a href="project_details.php?domain=<?php echo urlencode($domainNumber); ?>&id=<?php echo urlencode($project['Project_ID']); ?>" class="btn btn-sm btn-info">
|
| 304 |
+
<i class="fas fa-info-circle"></i> Details
|
| 305 |
+
</a>
|
| 306 |
+
</td>
|
| 307 |
+
</tr>
|
| 308 |
+
<?php endforeach; ?>
|
| 309 |
+
</tbody>
|
| 310 |
+
</table>
|
| 311 |
+
</div>
|
| 312 |
+
<?php else: ?>
|
| 313 |
+
<div class="alert alert-info">
|
| 314 |
+
<i class="fas fa-info-circle me-2"></i> No projects found for this student.
|
| 315 |
+
</div>
|
| 316 |
+
<?php endif; ?>
|
| 317 |
+
</div>
|
| 318 |
+
</div>
|
| 319 |
+
</div>
|
| 320 |
+
</div>
|
| 321 |
+
|
| 322 |
+
<?php
|
| 323 |
+
// Include footer
|
| 324 |
+
include 'includes/footer.php';
|
| 325 |
+
|
| 326 |
+
// Close connection
|
| 327 |
+
$conn->close();
|
| 328 |
+
?>
|
students.php
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Include database connection and authentication
|
| 3 |
+
require_once 'includes/db_connect.php';
|
| 4 |
+
require_once 'includes/auth_check.php';
|
| 5 |
+
|
| 6 |
+
// This page is for faculty only
|
| 7 |
+
requireFaculty();
|
| 8 |
+
|
| 9 |
+
// Initialize variables
|
| 10 |
+
$students = [];
|
| 11 |
+
$searchTerm = '';
|
| 12 |
+
$error = '';
|
| 13 |
+
|
| 14 |
+
// Check if students_info table exists
|
| 15 |
+
$tableCheckQuery = "SHOW TABLES LIKE 'students_info'";
|
| 16 |
+
$tableExists = $conn->query($tableCheckQuery)->num_rows > 0;
|
| 17 |
+
|
| 18 |
+
if ($tableExists) {
|
| 19 |
+
// Get student data structure
|
| 20 |
+
$columnsQuery = "SHOW COLUMNS FROM students_info";
|
| 21 |
+
$columnsResult = $conn->query($columnsQuery);
|
| 22 |
+
$studentIdField = null;
|
| 23 |
+
$studentNameFields = [];
|
| 24 |
+
|
| 25 |
+
// Find student ID and name fields
|
| 26 |
+
while ($column = $columnsResult->fetch_assoc()) {
|
| 27 |
+
if (preg_match('/(student|stud|roll)[\s_-]?(id|number|no)/i', $column['Field'])) {
|
| 28 |
+
$studentIdField = $column['Field'];
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
if (preg_match('/(student|stud)[\s_-]?(name)/i', $column['Field']) ||
|
| 32 |
+
preg_match('/(first|last|full)[\s_-]?(name)/i', $column['Field'])) {
|
| 33 |
+
$studentNameFields[] = $column['Field'];
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
// Handle search
|
| 38 |
+
if (isset($_GET['search']) && !empty($_GET['search'])) {
|
| 39 |
+
$searchTerm = trim($_GET['search']);
|
| 40 |
+
|
| 41 |
+
// Prepare search conditions
|
| 42 |
+
$conditions = [];
|
| 43 |
+
$params = [];
|
| 44 |
+
$types = '';
|
| 45 |
+
|
| 46 |
+
// Search by ID
|
| 47 |
+
if ($studentIdField) {
|
| 48 |
+
$conditions[] = "$studentIdField LIKE ?";
|
| 49 |
+
$params[] = "%$searchTerm%";
|
| 50 |
+
$types .= 's';
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// Search by name fields
|
| 54 |
+
foreach ($studentNameFields as $field) {
|
| 55 |
+
$conditions[] = "$field LIKE ?";
|
| 56 |
+
$params[] = "%$searchTerm%";
|
| 57 |
+
$types .= 's';
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
if (!empty($conditions)) {
|
| 61 |
+
$sql = "SELECT * FROM students_info WHERE " . implode(' OR ', $conditions);
|
| 62 |
+
$stmt = $conn->prepare($sql);
|
| 63 |
+
|
| 64 |
+
if (!empty($params)) {
|
| 65 |
+
$stmt->bind_param($types, ...$params);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
$stmt->execute();
|
| 69 |
+
$result = $stmt->get_result();
|
| 70 |
+
|
| 71 |
+
if ($result) {
|
| 72 |
+
while ($row = $result->fetch_assoc()) {
|
| 73 |
+
$students[] = $row;
|
| 74 |
+
}
|
| 75 |
+
} else {
|
| 76 |
+
$error = "Error executing search query: " . $conn->error;
|
| 77 |
+
}
|
| 78 |
+
} else {
|
| 79 |
+
$error = "No suitable fields found for searching.";
|
| 80 |
+
}
|
| 81 |
+
} else {
|
| 82 |
+
// Get all students if no search
|
| 83 |
+
$sql = "SELECT * FROM students_info";
|
| 84 |
+
$result = $conn->query($sql);
|
| 85 |
+
|
| 86 |
+
if ($result) {
|
| 87 |
+
while ($row = $result->fetch_assoc()) {
|
| 88 |
+
$students[] = $row;
|
| 89 |
+
}
|
| 90 |
+
} else {
|
| 91 |
+
$error = "Error fetching students: " . $conn->error;
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
} else {
|
| 95 |
+
$error = "Student information table not found in the database.";
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
// Include header
|
| 99 |
+
include 'includes/header.php';
|
| 100 |
+
?>
|
| 101 |
+
|
| 102 |
+
<div class="row mb-4">
|
| 103 |
+
<div class="col-md-12">
|
| 104 |
+
<nav aria-label="breadcrumb">
|
| 105 |
+
<ol class="breadcrumb">
|
| 106 |
+
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
|
| 107 |
+
<li class="breadcrumb-item active">Students</li>
|
| 108 |
+
</ol>
|
| 109 |
+
</nav>
|
| 110 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 111 |
+
<h2><i class="fas fa-user-graduate me-2"></i> Students Information</h2>
|
| 112 |
+
</div>
|
| 113 |
+
<p class="lead">View and search for student details</p>
|
| 114 |
+
</div>
|
| 115 |
+
</div>
|
| 116 |
+
|
| 117 |
+
<div class="row mb-4">
|
| 118 |
+
<div class="col-md-12">
|
| 119 |
+
<div class="card shadow-sm">
|
| 120 |
+
<div class="card-body">
|
| 121 |
+
<form method="GET" action="students.php" class="row g-3">
|
| 122 |
+
<div class="col-md-10">
|
| 123 |
+
<div class="input-group">
|
| 124 |
+
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
| 125 |
+
<input type="text" name="search" class="form-control" placeholder="Search by ID or name" value="<?php echo htmlspecialchars($searchTerm); ?>">
|
| 126 |
+
</div>
|
| 127 |
+
</div>
|
| 128 |
+
<div class="col-md-2">
|
| 129 |
+
<button type="submit" class="btn btn-primary w-100">Search</button>
|
| 130 |
+
</div>
|
| 131 |
+
</form>
|
| 132 |
+
</div>
|
| 133 |
+
</div>
|
| 134 |
+
</div>
|
| 135 |
+
</div>
|
| 136 |
+
|
| 137 |
+
<?php if (!empty($error)): ?>
|
| 138 |
+
<div class="alert alert-danger">
|
| 139 |
+
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error; ?>
|
| 140 |
+
</div>
|
| 141 |
+
<?php endif; ?>
|
| 142 |
+
|
| 143 |
+
<div class="row">
|
| 144 |
+
<div class="col-md-12">
|
| 145 |
+
<div class="card shadow-sm">
|
| 146 |
+
<div class="card-header bg-primary text-white">
|
| 147 |
+
<h5 class="mb-0"><i class="fas fa-list me-2"></i> Students List</h5>
|
| 148 |
+
</div>
|
| 149 |
+
<div class="card-body">
|
| 150 |
+
<?php if (count($students) > 0): ?>
|
| 151 |
+
<div class="table-responsive">
|
| 152 |
+
<table class="table table-striped table-hover">
|
| 153 |
+
<thead class="table-light">
|
| 154 |
+
<tr>
|
| 155 |
+
<?php
|
| 156 |
+
// Get the first student to determine columns
|
| 157 |
+
$firstStudent = $students[0];
|
| 158 |
+
foreach ($firstStudent as $key => $value):
|
| 159 |
+
?>
|
| 160 |
+
<th><?php echo htmlspecialchars($key); ?></th>
|
| 161 |
+
<?php endforeach; ?>
|
| 162 |
+
<th>Actions</th>
|
| 163 |
+
</tr>
|
| 164 |
+
</thead>
|
| 165 |
+
<tbody>
|
| 166 |
+
<?php foreach ($students as $student): ?>
|
| 167 |
+
<tr>
|
| 168 |
+
<?php foreach ($student as $key => $value): ?>
|
| 169 |
+
<td><?php echo htmlspecialchars($value); ?></td>
|
| 170 |
+
<?php endforeach; ?>
|
| 171 |
+
<td>
|
| 172 |
+
<?php if (isset($studentIdField) && isset($student[$studentIdField])): ?>
|
| 173 |
+
<a href="student_projects.php?id=<?php echo urlencode($student[$studentIdField]); ?>" class="btn btn-sm btn-info">
|
| 174 |
+
<i class="fas fa-project-diagram"></i> View Projects
|
| 175 |
+
</a>
|
| 176 |
+
<?php endif; ?>
|
| 177 |
+
</td>
|
| 178 |
+
</tr>
|
| 179 |
+
<?php endforeach; ?>
|
| 180 |
+
</tbody>
|
| 181 |
+
</table>
|
| 182 |
+
</div>
|
| 183 |
+
<?php else: ?>
|
| 184 |
+
<div class="alert alert-info">
|
| 185 |
+
<i class="fas fa-info-circle me-2"></i> No students found.
|
| 186 |
+
</div>
|
| 187 |
+
<?php endif; ?>
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
</div>
|
| 191 |
+
</div>
|
| 192 |
+
|
| 193 |
+
<?php
|
| 194 |
+
// Include footer
|
| 195 |
+
include 'includes/footer.php';
|
| 196 |
+
|
| 197 |
+
// Close connection
|
| 198 |
+
$conn->close();
|
| 199 |
+
?>
|
| 200 |
+
|
| 201 |
+
|
styles.css
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Global Styles */
|
| 2 |
+
:root {
|
| 3 |
+
--primary-color: #0d6efd;
|
| 4 |
+
--secondary-color: #6c757d;
|
| 5 |
+
--dark-color: #212529;
|
| 6 |
+
--light-color: #f8f9fa;
|
| 7 |
+
--success-color: #198754;
|
| 8 |
+
--danger-color: #dc3545;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
body {
|
| 12 |
+
font-family: 'Roboto', sans-serif;
|
| 13 |
+
background-color: #f8f9fa;
|
| 14 |
+
color: #333;
|
| 15 |
+
min-height: 100vh;
|
| 16 |
+
display: flex;
|
| 17 |
+
flex-direction: column;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
main {
|
| 21 |
+
flex: 1;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
.container {
|
| 25 |
+
max-width: 1280px;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
/* Card Styles */
|
| 29 |
+
.card {
|
| 30 |
+
border: none;
|
| 31 |
+
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
| 32 |
+
overflow: hidden;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.card:hover {
|
| 36 |
+
transform: translateY(-5px);
|
| 37 |
+
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.card-header {
|
| 41 |
+
border-bottom: none;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
.domain-card:hover {
|
| 45 |
+
border-color: var(--primary-color);
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
/* Table Styles */
|
| 49 |
+
.table th {
|
| 50 |
+
font-weight: 600;
|
| 51 |
+
background-color: #f8f9fa;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.table-hover tbody tr:hover {
|
| 55 |
+
background-color: rgba(13, 110, 253, 0.05);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
/* Badge Styles */
|
| 59 |
+
.badge {
|
| 60 |
+
font-weight: 500;
|
| 61 |
+
padding: 0.35em 0.65em;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
/* Button Styles */
|
| 65 |
+
.btn {
|
| 66 |
+
border-radius: 0.35rem;
|
| 67 |
+
font-weight: 500;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
.btn-primary {
|
| 71 |
+
background-color: var(--primary-color);
|
| 72 |
+
border-color: var(--primary-color);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
.btn-primary:hover {
|
| 76 |
+
background-color: #0b5ed7;
|
| 77 |
+
border-color: #0a58ca;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
/* Navbar Styles */
|
| 81 |
+
.navbar {
|
| 82 |
+
padding: 0.75rem 1rem;
|
| 83 |
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.navbar-brand {
|
| 87 |
+
font-weight: 700;
|
| 88 |
+
letter-spacing: 0.5px;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
/* Footer Styles */
|
| 92 |
+
footer {
|
| 93 |
+
background-color: #343a40;
|
| 94 |
+
color: white;
|
| 95 |
+
padding: 30px 0;
|
| 96 |
+
margin-top: auto;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
footer a {
|
| 100 |
+
color: #adb5bd;
|
| 101 |
+
text-decoration: none;
|
| 102 |
+
transition: all 0.2s ease;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
footer a:hover {
|
| 106 |
+
color: white;
|
| 107 |
+
text-decoration: none;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
/* Auth Form Styles */
|
| 111 |
+
.auth-form {
|
| 112 |
+
max-width: 450px;
|
| 113 |
+
margin: 0 auto;
|
| 114 |
+
padding: 2rem;
|
| 115 |
+
background: white;
|
| 116 |
+
border-radius: 10px;
|
| 117 |
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
.auth-form .card-header {
|
| 121 |
+
background-color: transparent;
|
| 122 |
+
border-bottom: none;
|
| 123 |
+
text-align: center;
|
| 124 |
+
padding-bottom: 0;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
.auth-form .card-body {
|
| 128 |
+
padding-top: 0.5rem;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
.auth-form h3 {
|
| 132 |
+
font-weight: 600;
|
| 133 |
+
color: #343a40;
|
| 134 |
+
margin-bottom: 1.5rem;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
.form-control:focus {
|
| 138 |
+
border-color: #80bdff;
|
| 139 |
+
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
/* Project Details Page */
|
| 143 |
+
.project-details .card-title {
|
| 144 |
+
color: var(--primary-color);
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.project-details .card-subtitle {
|
| 148 |
+
font-size: 1rem;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
/* Admin Panel */
|
| 152 |
+
.admin-stats .card {
|
| 153 |
+
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.admin-stats .card i {
|
| 157 |
+
opacity: 0.8;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
.admin-stats .card:hover {
|
| 161 |
+
transform: translateY(-5px);
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
.admin-table th {
|
| 165 |
+
font-weight: 600;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
/* Domain Cards */
|
| 169 |
+
.domain-card {
|
| 170 |
+
border-radius: 8px;
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
.domain-card .card-header {
|
| 174 |
+
border-radius: 8px 8px 0 0;
|
| 175 |
+
padding: 1rem;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
.domain-card .card-body {
|
| 179 |
+
padding: 1.25rem;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.domain-card .badge {
|
| 183 |
+
font-weight: 500;
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
/* Project Details */
|
| 187 |
+
.project-header {
|
| 188 |
+
background-color: #f8f9fa;
|
| 189 |
+
border-radius: 10px;
|
| 190 |
+
padding: 20px;
|
| 191 |
+
margin-bottom: 20px;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
.project-info {
|
| 195 |
+
padding: 20px;
|
| 196 |
+
background-color: #fff;
|
| 197 |
+
border-radius: 10px;
|
| 198 |
+
margin-bottom: 20px;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
/* Student Profile */
|
| 202 |
+
.student-avatar {
|
| 203 |
+
width: 100px;
|
| 204 |
+
height: 100px;
|
| 205 |
+
object-fit: cover;
|
| 206 |
+
border-radius: 50%;
|
| 207 |
+
border: 3px solid #6c757d;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
.user-avatar {
|
| 211 |
+
width: 150px;
|
| 212 |
+
height: 150px;
|
| 213 |
+
object-fit: cover;
|
| 214 |
+
border-radius: 50%;
|
| 215 |
+
margin: 0 auto;
|
| 216 |
+
display: block;
|
| 217 |
+
border: 5px solid #f0f0f0;
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
/* Project Management Styles */
|
| 221 |
+
.project-card {
|
| 222 |
+
border-radius: 8px;
|
| 223 |
+
border-left: 4px solid #007bff;
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
.project-card.hardware {
|
| 227 |
+
border-left-color: #ffc107;
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
.project-card.software {
|
| 231 |
+
border-left-color: #17a2b8;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
.project-card .card-title {
|
| 235 |
+
font-weight: 600;
|
| 236 |
+
color: #343a40;
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
.project-card .card-subtitle {
|
| 240 |
+
font-size: 0.875rem;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
.project-card .card-text {
|
| 244 |
+
color: #6c757d;
|
| 245 |
+
min-height: 60px;
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
.project-card .card-footer {
|
| 249 |
+
background-color: transparent;
|
| 250 |
+
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
| 251 |
+
padding: 0.75rem 1.25rem;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
.btn-group-sm .btn {
|
| 255 |
+
margin-right: 2px;
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
.pagination .page-item.active .page-link {
|
| 259 |
+
background-color: var(--primary-color);
|
| 260 |
+
border-color: var(--primary-color);
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
.breadcrumb {
|
| 264 |
+
background-color: #f8f9fa;
|
| 265 |
+
padding: 0.75rem 1rem;
|
| 266 |
+
border-radius: 0.25rem;
|
| 267 |
+
margin-bottom: 1rem;
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
.form-label {
|
| 271 |
+
font-weight: 500;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
.required-field::after {
|
| 275 |
+
content: '*';
|
| 276 |
+
color: var(--danger-color);
|
| 277 |
+
margin-left: 4px;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
.delete-warning {
|
| 281 |
+
color: var(--danger-color);
|
| 282 |
+
font-weight: 500;
|
| 283 |
+
background-color: rgba(220, 53, 69, 0.1);
|
| 284 |
+
padding: 1rem;
|
| 285 |
+
border-radius: 0.25rem;
|
| 286 |
+
margin-bottom: 1rem;
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
/* Responsive Adjustments */
|
| 290 |
+
@media (max-width: 768px) {
|
| 291 |
+
.container {
|
| 292 |
+
padding-left: 1.5rem;
|
| 293 |
+
padding-right: 1.5rem;
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
.auth-form {
|
| 297 |
+
max-width: 100%;
|
| 298 |
+
padding: 0 1rem;
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
.project-header h1 {
|
| 302 |
+
font-size: 1.8rem;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
.domain-card .card-img-top {
|
| 306 |
+
height: 140px;
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
.project-action-buttons {
|
| 310 |
+
flex-direction: column;
|
| 311 |
+
width: 100%;
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
.project-action-buttons .btn {
|
| 315 |
+
margin-bottom: 0.5rem;
|
| 316 |
+
}
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
/* Animation */
|
| 320 |
+
@keyframes fadeIn {
|
| 321 |
+
from { opacity: 0; }
|
| 322 |
+
to { opacity: 1; }
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
.fade-in {
|
| 326 |
+
animation: fadeIn 0.5s ease-in;
|
| 327 |
+
}
|
| 328 |
+
|
| 329 |
+
/* Project Form Styles */
|
| 330 |
+
.dynamic-field {
|
| 331 |
+
animation: fadeIn 0.3s ease-in-out;
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
.field-option {
|
| 335 |
+
display: inline-block;
|
| 336 |
+
margin-right: 10px;
|
| 337 |
+
margin-bottom: 10px;
|
| 338 |
+
padding: 5px 10px;
|
| 339 |
+
border-radius: 15px;
|
| 340 |
+
background-color: #e9ecef;
|
| 341 |
+
font-size: 0.9rem;
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
.field-option:hover {
|
| 345 |
+
background-color: #dee2e6;
|
| 346 |
+
cursor: pointer;
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
.field-option.selected {
|
| 350 |
+
background-color: var(--primary-color);
|
| 351 |
+
color: white;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
/* Home Page Stats */
|
| 355 |
+
.stats-card {
|
| 356 |
+
text-align: center;
|
| 357 |
+
padding: 1.5rem 1rem;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
.stats-card .icon {
|
| 361 |
+
font-size: 2rem;
|
| 362 |
+
margin-bottom: 1rem;
|
| 363 |
+
color: #007bff;
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
.stats-card .count {
|
| 367 |
+
font-size: 2.5rem;
|
| 368 |
+
font-weight: 700;
|
| 369 |
+
margin-bottom: 0.5rem;
|
| 370 |
+
}
|
| 371 |
+
|
| 372 |
+
.stats-card .label {
|
| 373 |
+
font-size: 1rem;
|
| 374 |
+
text-transform: uppercase;
|
| 375 |
+
letter-spacing: 1px;
|
| 376 |
+
color: #6c757d;
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
/* Admin Panel Styles */
|
| 380 |
+
.stats-box {
|
| 381 |
+
padding: 1.5rem;
|
| 382 |
+
border-radius: 8px;
|
| 383 |
+
text-align: center;
|
| 384 |
+
margin-bottom: 1.5rem;
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
.stats-box.primary {
|
| 388 |
+
background-color: rgba(0, 123, 255, 0.1);
|
| 389 |
+
color: #007bff;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.stats-box.success {
|
| 393 |
+
background-color: rgba(40, 167, 69, 0.1);
|
| 394 |
+
color: #28a745;
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
.stats-box.warning {
|
| 398 |
+
background-color: rgba(255, 193, 7, 0.1);
|
| 399 |
+
color: #ffc107;
|
| 400 |
+
}
|
| 401 |
+
|
| 402 |
+
.stats-box.danger {
|
| 403 |
+
background-color: rgba(220, 53, 69, 0.1);
|
| 404 |
+
color: #dc3545;
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
.stats-box .count {
|
| 408 |
+
font-size: 2.5rem;
|
| 409 |
+
font-weight: 700;
|
| 410 |
+
margin-bottom: 0.5rem;
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
.stats-box .label {
|
| 414 |
+
font-size: 0.9rem;
|
| 415 |
+
text-transform: uppercase;
|
| 416 |
+
letter-spacing: 1px;
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
.stats-box .icon {
|
| 420 |
+
font-size: 1.5rem;
|
| 421 |
+
margin-bottom: 0.75rem;
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
.user-table th, .user-table td {
|
| 425 |
+
vertical-align: middle;
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
.user-table .status-badge {
|
| 429 |
+
width: 85px;
|
| 430 |
+
}
|
| 431 |
+
|
| 432 |
+
/* Project Details Page */
|
| 433 |
+
.project-details .badge {
|
| 434 |
+
font-size: 0.875rem;
|
| 435 |
+
padding: 0.4em 0.8em;
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
.project-details dt {
|
| 439 |
+
font-weight: 600;
|
| 440 |
+
color: #343a40;
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
.project-details dd {
|
| 444 |
+
margin-bottom: 1rem;
|
| 445 |
+
}
|
| 446 |
+
|
| 447 |
+
.students-list {
|
| 448 |
+
list-style-type: none;
|
| 449 |
+
padding-left: 0;
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
.students-list li {
|
| 453 |
+
padding: 0.5rem 0;
|
| 454 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
.students-list li:last-child {
|
| 458 |
+
border-bottom: none;
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
/* Form Styles */
|
| 462 |
+
.form-group label {
|
| 463 |
+
font-weight: 500;
|
| 464 |
+
color: #343a40;
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
.invalid-feedback {
|
| 468 |
+
font-size: 80%;
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
/* Helper Classes */
|
| 472 |
+
.text-with-icon {
|
| 473 |
+
display: flex;
|
| 474 |
+
align-items: center;
|
| 475 |
+
}
|
| 476 |
+
|
| 477 |
+
.text-with-icon i {
|
| 478 |
+
margin-right: 0.5rem;
|
| 479 |
+
}
|
| 480 |
+
|
| 481 |
+
/* Project Management */
|
| 482 |
+
.project-form {
|
| 483 |
+
background-color: white;
|
| 484 |
+
border-radius: 10px;
|
| 485 |
+
padding: 2rem;
|
| 486 |
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
|
| 487 |
+
}
|
| 488 |
+
|
| 489 |
+
.dynamic-fields-container .form-group {
|
| 490 |
+
position: relative;
|
| 491 |
+
padding-right: 50px;
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
+
.dynamic-fields-container .remove-field {
|
| 495 |
+
position: absolute;
|
| 496 |
+
right: 15px;
|
| 497 |
+
top: 32px;
|
| 498 |
+
}
|
| 499 |
+
|
| 500 |
+
.recent-projects-table tr {
|
| 501 |
+
transition: background-color 0.2s ease;
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
.recent-projects-table tr:hover {
|
| 505 |
+
background-color: rgba(0, 123, 255, 0.05);
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
/* My Projects Page */
|
| 509 |
+
.my-projects-header {
|
| 510 |
+
background-color: #f8f9fa;
|
| 511 |
+
padding: 2rem 0;
|
| 512 |
+
margin-bottom: 2rem;
|
| 513 |
+
border-radius: 8px;
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
.my-projects-header h1 {
|
| 517 |
+
margin-bottom: 1rem;
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
/* Student Projects Page */
|
| 521 |
+
.student-info-card {
|
| 522 |
+
background-color: rgba(0, 123, 255, 0.05);
|
| 523 |
+
border-radius: 8px;
|
| 524 |
+
padding: 1.5rem;
|
| 525 |
+
margin-bottom: 2rem;
|
| 526 |
+
}
|
| 527 |
+
|
| 528 |
+
.student-info-card h4 {
|
| 529 |
+
margin-bottom: 1rem;
|
| 530 |
+
color: #007bff;
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
+
.student-info-card p {
|
| 534 |
+
margin-bottom: 0.5rem;
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
/* Button Hover Effects */
|
| 538 |
+
.btn {
|
| 539 |
+
transition: all 0.2s ease;
|
| 540 |
+
}
|
| 541 |
+
|
| 542 |
+
.btn-outline-primary:hover,
|
| 543 |
+
.btn-outline-success:hover,
|
| 544 |
+
.btn-outline-danger:hover {
|
| 545 |
+
transform: translateY(-2px);
|
| 546 |
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
| 547 |
+
}
|