Files
alrahma_sunday_school_api/app/Http/Controllers/Api/LandingPageController.php
T
2026-03-05 12:29:37 -05:00

379 lines
14 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Api;
use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\Invoice;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Models\UserRole;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response;
class LandingPageController extends BaseApiController
{
protected Configuration $config;
protected StudentClass $studentClass;
protected Invoice $invoice;
protected UserRole $userRole;
protected TeacherClass $teacherClass;
protected string $schoolYear;
protected string $semester;
protected ?string $lastDayOfRegistration;
protected ?string $refundDeadline;
protected ?int $classSectionId;
public function __construct()
{
parent::__construct();
$this->config = model(Configuration::class);
$this->studentClass = model(StudentClass::class);
$this->invoice = model(Invoice::class);
$this->userRole = model(UserRole::class);
$this->teacherClass = model(TeacherClass::class);
// Fetch Enrollment and Refund Deadlines from Configuration
$this->schoolYear = (string) ($this->config->getConfig('school_year') ?? '');
$this->semester = (string) ($this->config->getConfig('semester') ?? '');
$this->lastDayOfRegistration = $this->config->getConfig('enrollment_deadline') ?? 'Not set';
$this->refundDeadline = $this->config->getConfig('refund_deadline') ?? 'Not set';
// Get class_id and store it in session
$this->classSectionId = $this->classSectionId();
if ($this->classSectionId) {
session()->put('class_section_id', $this->classSectionId);
}
}
/**
* GET /api/v1/landing
* Get landing page data based on user role
*/
public function index()
{
$user = $this->getCurrentUser();
if (!$user) {
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
}
$userRole = $this->getUserRole();
$role = strtolower($userRole);
switch ($role) {
case 'administrator':
return $this->administrator();
case 'admin':
return $this->admin();
case 'teacher':
return $this->teacher();
case 'student':
return $this->student();
case 'parent':
case 'authorized_user':
return $this->parentDashboard();
default:
return $this->guest();
}
}
/**
* GET /api/v1/landing/data
* Get basic landing page data (backward compatibility)
*/
public function getData()
{
$user = $this->getCurrentUser();
if (!$user) {
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
}
try {
$payload = [
'school_year' => $this->schoolYear,
'semester' => $this->semester,
'enrollment_deadline' => $this->lastDayOfRegistration,
'refund_deadline' => $this->refundDeadline,
'class_section_id' => $this->classSectionId,
'user_role' => session()->get('active_role') ?? $this->getUserRole(),
];
return $this->success($payload, 'Landing page data retrieved successfully');
} catch (\Throwable $e) {
log_message('error', 'Landing page data error: ' . $e->getMessage());
return $this->respondError('Failed to retrieve landing page data', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function classSectionId(): ?int
{
$userId = $this->getCurrentUserId();
if (!$userId) {
return null;
}
$teacherClass = $this->teacherClass->getClassSectionIdByUserId($userId);
if (!$teacherClass) {
return null;
}
return (int) ($teacherClass['class_section_id'] ?? null);
}
protected function administrator()
{
return $this->success([
'role' => 'administrator',
'school_year' => $this->schoolYear,
'semester' => $this->semester,
'enrollment_deadline' => $this->lastDayOfRegistration,
'refund_deadline' => $this->refundDeadline,
], 'Administrator dashboard data');
}
protected function admin()
{
return $this->success([
'role' => 'admin',
'school_year' => $this->schoolYear,
'semester' => $this->semester,
'enrollment_deadline' => $this->lastDayOfRegistration,
'refund_deadline' => $this->refundDeadline,
], 'Admin dashboard data');
}
protected function teacher()
{
return $this->success([
'role' => 'teacher',
'class_section_id' => $this->classSectionId,
'school_year' => $this->schoolYear,
'semester' => $this->semester,
'enrollment_deadline' => $this->lastDayOfRegistration,
'refund_deadline' => $this->refundDeadline,
], 'Teacher dashboard data');
}
protected function student()
{
return $this->success([
'role' => 'student',
'school_year' => $this->schoolYear,
'semester' => $this->semester,
'enrollment_deadline' => $this->lastDayOfRegistration,
'refund_deadline' => $this->refundDeadline,
], 'Student dashboard data');
}
protected function parentDashboard()
{
$user = $this->getCurrentUser();
if (!$user) {
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
}
$parentId = $user->id;
$userType = session()->get('user_type');
// Map user type to roles
if ($userType === 'primary') {
$parentId = $parentId;
} elseif ($userType === 'secondary') {
// If user type is 'Secondary', find the parent_id from the parents table
$parentData = DB::table('parents')
->select('parent_id')
->where('secondparent_user_id', $parentId)
->first();
if ($parentData) {
$parentId = $parentData->parent_id;
}
} elseif ($userType === 'tertiary') {
// If user type is 'Tertiary', find the parent_id from the authorized_users table
$authUserData = DB::table('authorized_users')
->select('user_id as parent_id')
->where('authorized_user_id', $parentId)
->first();
if ($authUserData) {
$parentId = $authUserData->parent_id;
}
}
// If no firstparent ID is found, show an error
if (!$parentId) {
return $this->respondError('Unable to retrieve student data. Please contact support.', Response::HTTP_NOT_FOUND);
}
try {
// Fetch Notifications (only active, non-expired, non-deleted)
$notifications = DB::table('notifications')
->select([
'notifications.id',
'notifications.title',
'notifications.message',
'notifications.target_group',
'notifications.created_at',
'notifications.expires_at',
'user_notifications.user_id',
DB::raw("CASE
WHEN user_notifications.user_id IS NOT NULL THEN 'personal'
ELSE 'broadcast'
END as notification_type")
])
->leftJoin('user_notifications', function ($join) use ($parentId) {
$join->on('user_notifications.notification_id', '=', 'notifications.id')
->where('user_notifications.user_id', '=', $parentId);
})
->where(function ($query) use ($parentId) {
$query->where('notifications.target_group', 'parent')
->orWhere('user_notifications.user_id', $parentId);
})
->whereNull('notifications.deleted_at')
->where(function ($query) {
$query->whereNull('notifications.expires_at')
->orWhere('notifications.expires_at', '>', DB::raw('NOW()'));
})
->groupBy('notifications.id', 'notifications.title', 'notifications.message',
'notifications.target_group', 'notifications.created_at',
'notifications.expires_at', 'user_notifications.user_id')
->orderBy('notifications.created_at', 'DESC')
->get()
->map(function ($item) {
return (array) $item;
})
->toArray();
// Fetch Student Information (no filtering needed by school year or semester)
$students = DB::table('students')
->where('parent_id', $parentId)
->get()
->map(function ($student) {
$studentArray = (array) $student;
// Get class_section_name and treat it as grade
$classSection = $this->studentClass->getClassSectionsByStudentId($student->id, $this->schoolYear);
$studentArray['class_section'] = $classSection;
$studentArray['grade'] = $classSection; // grade same as section
return $studentArray;
})
->toArray();
// Fetch Attendance Records (filtered by most recent school year and semester)
$attendanceData = DB::table('attendance_data')
->select('attendance_data.*', 'students.firstname', 'students.lastname')
->join('students', 'students.id', '=', 'attendance_data.student_id')
->where('students.parent_id', $parentId)
->where('attendance_data.school_year', $this->schoolYear)
->where('attendance_data.semester', $this->semester)
->orderBy('attendance_data.date', 'DESC')
->get()
->map(function ($item) {
return (array) $item;
})
->toArray();
// Fetch Grades (filtered by most recent school year and semester)
$grades = DB::table('final_score')
->select('final_score.*', 'students.firstname', 'students.lastname')
->join('students', 'students.id', '=', 'final_score.student_id')
->where('students.parent_id', $parentId)
->where('final_score.school_year', $this->schoolYear)
->where('final_score.semester', $this->semester)
->orderBy('final_score.created_at', 'DESC')
->get()
->map(function ($item) {
return (array) $item;
})
->toArray();
// Fetch Enrollments (filtered by most recent school year and semester)
$enrollments = DB::table('enrollments')
->select('enrollments.*', 'classes.class_name')
->join('students', 'students.id', '=', 'enrollments.student_id')
->join('classes', 'classes.id', '=', 'enrollments.class_section_id')
->where('students.parent_id', $parentId)
->where('enrollments.school_year', $this->schoolYear)
->where('enrollments.semester', $this->semester)
->orderBy('enrollments.enrollment_date', 'DESC')
->get()
->map(function ($item) {
return (array) $item;
})
->toArray();
// Fetch latest invoice balance
$paymentBalance = $this->invoice->getLatestInvoiceTotalAmount($parentId);
return $this->success([
'role' => 'parent',
'notifications' => $notifications,
'students' => $students,
'attendance' => $attendanceData,
'grades' => $grades,
'enrollments' => $enrollments,
'lastDayOfRegistration' => $this->lastDayOfRegistration,
'withdrawalDeadline' => $this->refundDeadline,
'paymentBalance' => $paymentBalance,
'school_year' => $this->schoolYear,
'semester' => $this->semester,
], 'Parent dashboard data retrieved successfully');
} catch (\Throwable $e) {
log_message('error', 'Parent dashboard error: ' . $e->getMessage());
return $this->respondError('Failed to retrieve parent dashboard data: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function guest()
{
return $this->success([
'role' => 'guest',
'school_year' => $this->schoolYear,
'semester' => $this->semester,
], 'Guest dashboard data');
}
protected function getUserRole(): string
{
// Try to get from session first
$role = session()->get('user_role');
if ($role) {
return $role;
}
// Try active_role
$role = session()->get('active_role');
if ($role) {
return $role;
}
// Get from current user's roles
$user = $this->getCurrentUser();
if ($user && !empty($user->roles)) {
return $user->roles[0] ?? 'guest';
}
// Fallback to database lookup
$userId = $this->getCurrentUserId();
if ($userId) {
return $this->getUserRoleFromDatabase($userId);
}
return 'guest';
}
protected function getUserRoleFromDatabase($userId): string
{
try {
$roles = $this->userRole->getRolesByUserId($userId);
if (!empty($roles) && isset($roles[0]['role_name'])) {
return $roles[0]['role_name'];
}
} catch (\Throwable $e) {
log_message('error', 'Failed to get user role from database: ' . $e->getMessage());
}
return 'guest';
}
}