user(); // Super admin always gets dashboard if ($user->type === 'superadmin' || $user->type === 'super admin') { return $this->renderDashboard(); } // Check if user has dashboard permission (skip if permission doesn't exist) try { if ($user->hasPermissionTo('manage-dashboard')) { return $this->renderDashboard(); } } catch (\Exception $e) { // Permission doesn't exist, continue to dashboard for authenticated users return $this->renderDashboard(); } // Redirect to first available page return $this->redirectToFirstAvailablePage(); } public function redirectToFirstAvailablePage() { $user = auth()->user(); // Define available routes with their permissions $routes = [ ['route' => 'users.index', 'permission' => 'manage-users'], ['route' => 'roles.index', 'permission' => 'manage-roles'], ['route' => 'plans.index', 'permission' => 'manage-plans'], ['route' => 'referral.index', 'permission' => 'manage-referral'], ['route' => 'settings.index', 'permission' => 'manage-settings'], ]; // Find first available route foreach ($routes as $routeData) { if ($user->hasPermissionTo($routeData['permission'])) { return redirect()->route($routeData['route']); } } // If no permissions found, logout user auth()->logout(); return redirect()->route('login')->with('error', __('No access permissions found.')); } private function renderDashboard() { $user = auth()->user(); if ($user->type === 'superadmin' || $user->type === 'super admin') { return $this->renderSuperAdminDashboard(); } else { return $this->renderCompanyDashboard(); } } private function renderSuperAdminDashboard() { // Get system-wide statistics $totalCompanies = User::where('type', 'company')->count(); $totalUsers = User::where('type', '!=', 'superadmin')->where('type', '!=', 'super admin')->count(); $totalRevenue = PlanOrder::where('status', 'approved')->sum('final_price') ?? 0; $activePlans = Plan::where('is_plan_enable', 'on')->count(); $pendingRequests = PlanRequest::where('status', 'pending')->count(); $activeCoupons = Coupon::where('status', true)->count(); // Calculate monthly growth for companies $currentMonthCompanies = User::where('type', 'company') ->whereMonth('created_at', now()->month) ->whereYear('created_at', now()->year) ->count(); $previousMonthCompanies = User::where('type', 'company') ->whereMonth('created_at', now()->subMonth()->month) ->whereYear('created_at', now()->subMonth()->year) ->count(); $monthlyGrowth = isDemo() ? 90 : ($previousMonthCompanies > 0 ? round((($currentMonthCompanies - $previousMonthCompanies) / $previousMonthCompanies) * 100, 1) : ($currentMonthCompanies > 0 ? 100 : 0)); $dashboardData = [ 'stats' => [ 'totalCompanies' => $totalCompanies, 'totalUsers' => $totalUsers, 'totalRevenue' => $totalRevenue, 'activePlans' => $activePlans, 'pendingRequests' => $pendingRequests, 'monthlyGrowth' => $monthlyGrowth, 'activeCoupons' => $activeCoupons, ], 'recentActivity' => User::where('type', 'company') ->orderBy('created_at', 'desc') ->take(5) ->get(['id', 'name', 'email', 'created_at']) ->map(function ($company) { return [ 'id' => $company->id, 'name' => $company->name, 'email' => $company->email, 'registered_at' => $company->created_at->diffForHumans(), 'status' => 'active', ]; }), 'topPlans' => Plan::withCount('users') ->orderBy('users_count', 'desc') ->take(5) ->get() ->map(function ($plan) { return [ 'name' => $plan->name, 'subscribers' => $plan->users_count, 'revenue' => $plan->users_count * $plan->price, ]; }), ]; return Inertia::render('superadmin/dashboard', props: [ 'dashboardData' => $dashboardData, ]); } private function renderCompanyDashboard() { $user = auth()->user(); // If user is employee, show limited dashboard if ($user->type === 'employee') { return $this->renderEmployeeDashboard(); } $companyUserIds = $this->getCompanyUserIds(); // Core HR Statistics $totalEmployees = User::where('type', 'employee')->whereIn('created_by', $companyUserIds)->count(); $totalBranches = Branch::whereIn('created_by', $companyUserIds)->count(); $totalDepartments = Department::whereIn('created_by', $companyUserIds)->count(); // Monthly Statistics if (isDemo()) { $newEmployeesThisMonth = Employee::whereIn('created_by', $companyUserIds)->count(); $jobPostsThisMonth = JobPosting::whereIn('created_by', $companyUserIds)->count(); $candidatesThisMonth = Candidate::whereIn('created_by', $companyUserIds)->count(); } else { $newEmployeesThisMonth = Employee::whereIn('created_by', $companyUserIds) ->whereMonth('created_at', now()->month)->count(); $jobPostsThisMonth = JobPosting::whereIn('created_by', $companyUserIds) ->whereMonth('created_at', now()->month)->count(); $candidatesThisMonth = Candidate::whereIn('created_by', $companyUserIds) ->whereMonth('created_at', now()->month)->count(); } // Attendance Statistics if (isDemo()) { $presentToday = 45; $attendanceRate = 85.5; } else { $presentToday = AttendanceRecord::whereIn('created_by', $companyUserIds) ->whereDate('date', today())->where('status', 'present')->count(); $attendanceRate = $totalEmployees > 0 ? round(($presentToday / $totalEmployees) * 100, 1) : 0; } // Leave Statistics $pendingLeaves = LeaveApplication::whereIn('created_by', $companyUserIds) ->where('status', 'pending')->count(); $onLeaveToday = LeaveApplication::whereIn('created_by', $companyUserIds) ->where('status', 'approved'); $onLeaveToday = $onLeaveToday->whereDate('start_date', '<=', today()) ->whereDate('end_date', '>=', today())->count(); // Recruitment Statistics $activeJobPostings = JobPosting::whereIn('created_by', $companyUserIds) ->where('status', 'Published')->count(); $totalCandidates = Candidate::whereIn('created_by', $companyUserIds)->count(); // Department Distribution for Chart // $predefinedColors = ['#4F46E5', '#10b77f', '#F59E0B', '#EF4444', '#3B82F6', '#D946EF']; $predefinedColors = ['#0EA5E9', '#14B8A6', '#6366F1', '#0D9488', '#7C3AED', '#0369A1']; $departmentStats = Department::whereIn('created_by', $companyUserIds) ->withCount('employees') ->with('branch') ->orderBy('employees_count', 'desc') ->when(config('app.is_demo') == true, function ($query) { return $query->take(6); }) ->get() ->map(function ($dept, $index) use ($predefinedColors) { $displayName = $dept->name . ' (' . $dept->branch->name . ')'; return [ 'name' => $displayName, 'value' => $dept->employees_count, 'color' => config('app.is_demo') == true ? ($predefinedColors[$index] ?? '#' . substr(md5($displayName), 0, 6)) : '#' . substr(md5($displayName), 0, 6), ]; }); // Monthly Hiring Trend for Chart (last 6 months) if (isDemo()) { $hiringTrend = [ ['month' => now()->subMonths(5)->format('M Y'), 'hires' => 8], ['month' => now()->subMonths(4)->format('M Y'), 'hires' => 12], ['month' => now()->subMonths(3)->format('M Y'), 'hires' => 15], ['month' => now()->subMonths(2)->format('M Y'), 'hires' => 10], ['month' => now()->subMonths(1)->format('M Y'), 'hires' => 18], ['month' => now()->format('M Y'), 'hires' => 14], ]; } else { $hiringTrend = []; for ($i = 5; $i >= 0; $i--) { $month = now()->subMonths($i); $count = Employee::whereIn('created_by', $companyUserIds) ->whereMonth('created_at', $month->month) ->whereYear('created_at', $month->year) ->count(); $hiringTrend[] = [ 'month' => $month->format('M Y'), 'hires' => $count, ]; } } // Candidate Status Distribution for Chart $candidateStatusStats = Candidate::whereIn('created_by', $companyUserIds) ->selectRaw('status, COUNT(*) as count') ->groupBy('status') ->get() ->map(function ($item) { $colors = [ 'New' => '#0EA5E9', 'Screening' => '#F59E0B', 'Interview' => '#8B5CF6', 'Offer' => '#14B8A6', 'Hired' => '#10B981', 'Rejected' => '#EF4444', ]; return [ 'name' => $item->status, 'value' => $item->count, 'color' => $colors[$item->status] ?? '#6b7280', ]; }); // Leave Types for Chart $leaveTypesStats = LeaveType::whereIn('created_by', $companyUserIds) ->get() ->map(function ($leaveType) { return [ 'name' => $leaveType->name, 'value' => $leaveType->max_days_per_year, 'color' => $leaveType->color ?: '#' . substr(md5($leaveType->name), 0, 6), ]; }); // Employee Growth Chart (Monthly for current year) if (isDemo()) { $employeeGrowthChart = [ ['month' => 'January', 'employees' => 15], ['month' => 'February', 'employees' => 5], ['month' => 'March', 'employees' => 22], ['month' => 'April', 'employees' => 10], ['month' => 'May', 'employees' => 28], ['month' => 'June', 'employees' => 32], ['month' => 'July', 'employees' => 35], ['month' => 'August', 'employees' => 50], ['month' => 'September', 'employees' => 42], ['month' => 'October', 'employees' => 45], ['month' => 'November', 'employees' => 48], ['month' => 'December', 'employees' => 52], ]; } else { $employeeGrowthChart = []; for ($month = 1; $month <= 12; $month++) { $count = User::where('type', 'employee') ->whereIn('created_by', $companyUserIds) ->whereMonth('created_at', $month) ->whereYear('created_at', now()->year) ->count(); $employeeGrowthChart[] = [ 'month' => date('F', mktime(0, 0, 0, $month, 1)), 'employees' => $count, ]; } } // Recent Activities $recentLeaves = LeaveApplication::whereIn('created_by', $companyUserIds) ->with(['employee', 'leaveType']); if (config('app.is_demo') == true) { $recentLeaves = $recentLeaves->whereIn('status', ['approved', 'absent'])->get(); } else { $recentLeaves = $recentLeaves->whereIn('status', ['approved', 'absent']) ->whereDate('start_date', '<=', today()) ->whereDate('end_date', '>=', today()) ->get(); } $recentCandidates = Candidate::whereIn('created_by', $companyUserIds) ->with(['job']) ->orderBy('created_at', 'desc') ->take(5) ->get(); // Recent Announcements $recentAnnouncements = Announcement::whereIn('created_by', $companyUserIds) ->orderBy('created_at', 'desc') ->take(5) ->get(); // Recent Meetings $recentMeetings = Meeting::whereIn('created_by', $companyUserIds) ->orderBy('created_at', 'desc') ->take(5) ->get(); $dashboardData = [ 'stats' => [ 'totalEmployees' => $totalEmployees, 'totalBranches' => $totalBranches, 'totalDepartments' => $totalDepartments, 'newEmployeesThisMonth' => $newEmployeesThisMonth, 'jobPostsThisMonth' => $jobPostsThisMonth, 'candidatesThisMonth' => $candidatesThisMonth, 'attendanceRate' => $attendanceRate, 'presentToday' => $presentToday, 'pendingLeaves' => $pendingLeaves, 'onLeaveToday' => $onLeaveToday, 'activeJobPostings' => $activeJobPostings, 'totalCandidates' => $totalCandidates, ], 'charts' => [ 'departmentStats' => $departmentStats, 'hiringTrend' => $hiringTrend, 'candidateStatusStats' => $candidateStatusStats, 'leaveTypesStats' => $leaveTypesStats, 'employeeGrowthChart' => $employeeGrowthChart, ], 'recentActivities' => [ 'leaves' => $recentLeaves, 'candidates' => $recentCandidates, 'announcements' => $recentAnnouncements, 'meetings' => $recentMeetings, ], 'userType' => $user->type, ]; return Inertia::render('dashboard', [ 'dashboardData' => $dashboardData, ]); } private function renderEmployeeDashboard() { $user = auth()->user(); $companyUserIds = $this->getCompanyUserIds(); // Recent Announcements $recentAnnouncements = \App\Models\Announcement::whereIn('created_by', $companyUserIds) ->orderBy('created_at', 'desc') ->take(5) ->get(); // Recent Meetings - get meetings where user is organizer $recentMeetings = \App\Models\Meeting::with('attendees') ->whereIn('created_by', $companyUserIds) ->where('organizer_id', $user->id) ->orderBy('created_at', 'desc') ->get(); // Get meetings where user is attendee $meetingAttendee = \App\Models\MeetingAttendee::with('meeting') ->where('user_id', $user->id) ->get(); // Extract meetings from attendee records $attendeeMeetings = $meetingAttendee->pluck(value: 'meeting')->filter(); // Merge and remove duplicates $recentMeetings = $recentMeetings->merge($attendeeMeetings) ->unique('id') ->filter(function ($meeting) { return $meeting->meeting_date >= today(); }) ->sortByDesc('created_at') ->values(); // Employee Stats $totalAwards = \App\Models\Award::where('employee_id', $user->id)->count(); $totalWarnings = \App\Models\Warning::where('employee_id', $user->id)->count(); $totalComplaints = \App\Models\Complaint::where('against_employee_id', $user->id)->count(); // Get shifts and attendance policies for clock in functionality $shifts = \App\Models\Shift::whereIn('created_by', $companyUserIds) ->where('status', 'active') ->get(['id', 'name', 'start_time', 'end_time']); $attendancePolicies = \App\Models\AttendancePolicy::whereIn('created_by', $companyUserIds) ->where('status', 'active') ->get(['id', 'name']); // Get today's attendance for the employee $todayAttendance = AttendanceRecord::where('employee_id', $user->id) ->where('date', \Carbon\Carbon::today()) ->first(); // Get employee's assigned shift $employeeShift = null; $employee = Employee::where('user_id', $user->id)->first(); if ($employee && $employee->shift_id) { $employeeShift = Shift::find($employee->shift_id); } // Auto clock out previous days like yesterday and alll thing if not clocked out $previousAttendance = AttendanceRecord::where('employee_id', $user->id) ->where('date', '<', \Carbon\Carbon::today()) ->whereNotNull('clock_in') ->whereNull('clock_out') ->get(); foreach ($previousAttendance as $record) { $recordDate = \Carbon\Carbon::parse($record->date); $shift = Shift::find($record->shift_id) ?? $employeeShift; if ($shift) { $record->update([ 'clock_out' => $shift->end_time, ]); if (method_exists($record, 'processAttendance')) { $record->processAttendance(); } } } // Auto clock out if shift end time has passed for today // if ($todayAttendance && $todayAttendance->clock_in && !$todayAttendance->clock_out && $employeeShift) { // $now = \Carbon\Carbon::now(); // $shiftEndTime = \Carbon\Carbon::today()->setTimeFromTimeString($employeeShift->end_time); // if ($now->greaterThan($shiftEndTime)) { // $todayAttendance->update([ // 'clock_out' => $employeeShift->end_time, // ]); // if (method_exists($todayAttendance, 'processAttendance')) { // $todayAttendance->processAttendance(); // } // $todayAttendance = $todayAttendance->fresh(); // } // } $dashboardData = [ 'stats' => [ 'totalAwards' => $totalAwards, 'totalWarnings' => $totalWarnings, 'totalComplaints' => $totalComplaints, ], 'recentActivities' => [ 'announcements' => $recentAnnouncements, 'meetings' => $recentMeetings, ], 'shifts' => $shifts, 'attendancePolicies' => $attendancePolicies, 'todayAttendance' => $todayAttendance, 'currentTime' => \Carbon\Carbon::now()->format('H:i:s'), 'employeeShift' => $employeeShift, 'userType' => $user->type, ]; return Inertia::render('employee-dashboard', [ 'dashboardData' => $dashboardData, ]); } // private function getCompanyUserIds() // { // $user = auth()->user(); // if ($user->type === 'company') { // $companyUserIds = User::where('created_by', $user->id)->pluck('id')->toArray(); // $companyUserIds[] = $user->id; // return $companyUserIds; // } else { // $userCreatedBy = User::where('id', $user->created_by)->value('id'); // $companyUserIds = User::where('created_by', $userCreatedBy)->pluck('id')->toArray(); // $companyUserIds[] = $userCreatedBy; // return $companyUserIds; // } // } private function getCompanyUserIds() { $user = auth()->user(); if ($user->type === 'company') { $companyId = getCompanyId($user->id); if ($companyId) { $allUsers = getAllCompanyUsers($companyId); $allUsers[] = $companyId; // Include company itself return array_unique($allUsers); } return []; } else { $companyId = getCompanyId($user->id); if ($companyId) { $allUsers = getAllCompanyUsers($companyId); $allUsers[] = $companyId; // Include company itself return array_unique($allUsers); } return []; } } }