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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
611 changes: 595 additions & 16 deletions webapp/Controller/AdminController.php

Large diffs are not rendered by default.

123 changes: 117 additions & 6 deletions webapp/Controller/ParentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,26 @@ public function dashboard() {
error_log("Parent Dashboard - User Name: " . $user_name);
error_log("Parent Dashboard - Username: " . $username);

// Get parent-specific data from database
// Initialize default values
$parentData = null;
$children = [];
$payments = [];
$stats = [];
$stats = [
'total_children' => 0,
'total_classes' => 0,
'total_sessions' => 0,
'attended_sessions' => 0,
'total_payments' => 0,
'total_paid' => 0,
'average_attendance_rate' => 0
];
$notifications = [];
$connection_requests = [];

try {
// Get parent profile information
$parentData = $this->parentModel->getParentById($user_id);
error_log("Parent data loaded: " . ($parentData ? 'YES' : 'NO'));

// If we have parent data from DB and no user_name in session, use it
if ($parentData && empty($user_name)) {
Expand All @@ -46,18 +56,25 @@ public function dashboard() {

// Get parent's children
$children = $this->parentModel->getParentChildren($user_id);
error_log("Children loaded: " . count($children));

// Get payment records for all children
$payments = $this->parentModel->getChildrenPayments($user_id);
error_log("Payments loaded: " . count($payments));

// Get parent statistics
$stats = $this->parentModel->getParentStats($user_id);
error_log("Stats loaded: " . json_encode($stats));

// Get recent notifications
$notifications = $this->parentModel->getParentNotifications($user_id, 10);
error_log("Notifications loaded: " . count($notifications));

} catch (Exception $e) {
error_log("Error getting parent data: " . $e->getMessage());
error_log("CRITICAL ERROR in parent dashboard: " . $e->getMessage());
error_log("Stack trace: " . $e->getTraceAsString());

// Don't let the error crash the page, use default values
}

$data = [
Expand All @@ -70,14 +87,25 @@ public function dashboard() {
'children' => $children,
'payments' => $payments,
'stats' => $stats,
'notifications' => $notifications
'notifications' => $notifications,
'connection_requests' => $connection_requests
];

// Debug logging
error_log("Data passed to parent view - user_name: " . ($data['user_name'] ?? 'NULL'));
error_log("Children count: " . count($children));
error_log("Final stats: " . json_encode($stats));

// Render the Parent view
$this->renderView('Parent/Parent', $data);
try {
// Render the Parent view
$this->renderView('Parent/Parent', $data);
} catch (Exception $e) {
error_log("ERROR rendering parent view: " . $e->getMessage());
// Fallback error page
echo "<h1>Dashboard Error</h1>";
echo "<p>Sorry, there was an error loading your dashboard. Please try again later.</p>";
echo "<p><a href='/webapp/logout'>Logout</a></p>";
}
}

// API endpoints for parent dashboard
Expand Down Expand Up @@ -146,5 +174,88 @@ public function getPaymentHistory() {
exit();
}
}

public function getChildDetails() {
header('Content-Type: application/json');

try {
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'parent') {
http_response_code(401);
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit();
}

$childId = intval($_GET['child_id'] ?? 0);
$parentId = $_SESSION['user_id'];

if (!$childId) {
throw new Exception("Child ID is required");
}

$child = $this->parentModel->getChildDetails($childId, $parentId);

if (!$child) {
throw new Exception("Child not found or access denied");
}

echo json_encode([
'success' => true,
'child' => $child
]);

} catch (Exception $e) {
error_log("Error getting child details: " . $e->getMessage());
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
exit();
}

public function getChildAttendanceByClass() {
header('Content-Type: application/json');

try {
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'parent') {
http_response_code(401);
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit();
}

$childId = intval($_GET['child_id'] ?? 0);
$classId = intval($_GET['class_id'] ?? 0);
$parentId = $_SESSION['user_id'];

if (!$childId) {
throw new Exception("Child ID is required");
}

// Verify parent has access to this child
$child = $this->parentModel->getChildDetails($childId, $parentId);
if (!$child) {
throw new Exception("Access denied");
}

if ($classId) {
$attendance = $this->parentModel->getChildAttendanceByClass($childId, $classId);
} else {
$attendance = $this->parentModel->getChildAttendanceHistory($childId);
}

echo json_encode([
'success' => true,
'attendance' => $attendance
]);

} catch (Exception $e) {
error_log("Error getting child attendance: " . $e->getMessage());
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
exit();
}
}
?>
94 changes: 94 additions & 0 deletions webapp/Controller/StudentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,99 @@ public function changePassword() {
}
exit();
}

public function sendParentConnection() {
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'message' => 'Invalid request method']);
return;
}

// Check if user is logged in and is a student
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'student') {
echo json_encode(['success' => false, 'message' => 'Unauthorized access']);
return;
}

try {
$student_id = $_SESSION['user_id'];
$parent_email = trim($_POST['parent_email'] ?? '');
$parent_phone = trim($_POST['parent_phone'] ?? '');
$parent_name = trim($_POST['parent_name'] ?? '');
$message = trim($_POST['message'] ?? '');

// Validate required fields
if (empty($parent_email)) {
echo json_encode(['success' => false, 'message' => 'Email phụ huynh là bắt buộc']);
return;
}

// Validate email format
if (!filter_var($parent_email, FILTER_VALIDATE_EMAIL)) {
echo json_encode(['success' => false, 'message' => 'Email không hợp lệ']);
return;
}

// Use the studentModel's database connection
$db = $this->studentModel->getConnection();

// Check if parent already exists
$checkParentQuery = "SELECT id FROM users WHERE email = :email AND role = 'parent'";
$checkParentStmt = $db->prepare($checkParentQuery);
$checkParentStmt->bindParam(':email', $parent_email);
$checkParentStmt->execute();

$parent_id = null;
if ($checkParentStmt->rowCount() > 0) {
$parent = $checkParentStmt->fetch(PDO::FETCH_ASSOC);
$parent_id = $parent['id'];
} else {
// Create new parent account
$username = 'parent_' . uniqid();
$temp_password = bin2hex(random_bytes(8));
$hashed_password = password_hash($temp_password, PASSWORD_DEFAULT);

$createParentQuery = "INSERT INTO users (username, password, email, full_name, phone, role, is_active, created_at)
VALUES (:username, :password, :email, :full_name, :phone, 'parent', 1, NOW())";
$createParentStmt = $db->prepare($createParentQuery);
$createParentStmt->bindParam(':username', $username);
$createParentStmt->bindParam(':password', $hashed_password);
$createParentStmt->bindParam(':email', $parent_email);
$createParentStmt->bindParam(':full_name', $parent_name);
$createParentStmt->bindParam(':phone', $parent_phone);

if ($createParentStmt->execute()) {
$parent_id = $db->lastInsertId();
} else {
echo json_encode(['success' => false, 'message' => 'Không thể tạo tài khoản phụ huynh']);
return;
}
}

// Log the connection request for now
error_log("Parent connection request: Student ID $student_id wants to connect with Parent ID $parent_id (Email: $parent_email)");

echo json_encode([
'success' => true,
'message' => 'Đã gửi yêu cầu kết nối thành công! Phụ huynh sẽ nhận được thông báo qua email.'
]);

} catch (Exception $e) {
error_log("Send parent connection error: " . $e->getMessage());
echo json_encode(['success' => false, 'message' => 'Lỗi hệ thống: ' . $e->getMessage()]);
}
}
}
?>
private function getDbConnection() {
if (!$this->db) {
// If db is not set, create a new connection
require_once(__DIR__ . '/../config/database.php');
$database = new Database();
$this->db = $database->getConnection();
}
return $this->db;
}
}
?>
Loading