filled('search')) { $search = $request->search; $query->where(function($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('email', 'like', "%{$search}%") ->orWhere('designation', 'like', "%{$search}%") ->orWhere('phone', 'like', "%{$search}%"); }); } // 2. Department Filter if ($request->filled('department_id')) { $query->where('department_id', $request->department_id); } // 3. Status Filter if ($request->filled('status')) { $query->where('status', $request->status); } $staffMembers = $query->orderBy('name', 'asc')->paginate(12); $staffMembers->appends($request->query()); // Fetch dynamic dropdown lists $departments = Department::orderBy('name', 'asc')->get(); $countries = Country::orderBy('en_short_name', 'asc')->get(); $data = [ 'staffMembers' => $staffMembers, 'departments' => $departments, 'countries' => $countries, ]; return view('staff.index', $data); } public function store(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:200', 'designation' => 'required|string|max:191', 'email' => 'required|email|max:200', 'phone' => 'nullable|string|max:200', 'department_id' => 'required|integer', 'location_country' => 'nullable|string|max:191', 'status' => 'required|string|max:20', 'photo' => 'nullable|image|mimes:jpg,jpeg,png|max:2048', ]); if ($request->hasFile('photo')) { $validated['profile_pic'] = $request->file('photo')->store('staff_profiles', 'public'); } $validated['created_by'] = auth()->id() ?? 1; $validated['password'] = Hash::make('default_password'); $validated['hire_date'] = now(); StaffMember::create($validated); return response()->json(['success' => true, 'message' => 'Staff member added successfully!']); } public function update(Request $request, $id) { $staff = StaffMember::findOrFail($id); $validated = $request->validate([ 'name' => 'required|string|max:200', 'designation' => 'required|string|max:191', 'email' => 'required|email|max:200', 'phone' => 'nullable|string|max:200', 'department_id' => 'required|integer', 'location_country' => 'nullable|string|max:191', 'status' => 'required|string|max:20', 'photo' => 'nullable|image|mimes:jpg,jpeg,png|max:2048', ]); if ($request->hasFile('photo')) { if ($staff->profile_pic && Storage::disk('public')->exists($staff->profile_pic)) { Storage::disk('public')->delete($staff->profile_pic); } $validated['profile_pic'] = $request->file('photo')->store('staff_profiles', 'public'); } $validated['modified_by'] = auth()->id() ?? 1; $staff->update($validated); return response()->json(['success' => true, 'message' => 'Staff member updated successfully!']); } public function destroy($id) { $staff = StaffMember::findOrFail($id); if ($staff->profile_pic && Storage::disk('public')->exists($staff->profile_pic)) { Storage::disk('public')->delete($staff->profile_pic); } $staff->delete(); return redirect()->back()->with('success', 'Staff member removed.'); } public function getUpcomingBirthdays() { $today = Carbon::now(); $thirtyDaysFromNow = Carbon::now()->addDays(30); $currentMonthDay = $today->format('m-d'); $futureMonthDay = $thirtyDaysFromNow->format('m-d'); if ($currentMonthDay <= $futureMonthDay) { // Simple range check within the same calendar year $upcomingStaff = StaffMember::whereBetween('dob', [$currentMonthDay, $futureMonthDay]) ->orderBy('dob', 'asc') ->get(); } else { // Handles the year-end crossover (e.g., looking from December into January) $upcomingStaff = StaffMember::where(function($query) use ($currentMonthDay, $futureMonthDay) { $query->where('dob', '>=', $currentMonthDay) ->orWhere('dob', '<=', $futureMonthDay); }) ->orderBy('dob', 'asc') ->get(); } return $upcomingStaff; } }