feat: teams redesign — cards, filter, user autocomplete

- Teams index: cards with animation, search filter
- Team detail: user autocomplete via AJAX (search on type)
- CSS: card grid styles, autocomplete dropdown
- Backend: searchUsers endpoint, filter support
This commit is contained in:
2026-06-09 18:11:20 -04:00
parent b1fc0e2cfe
commit 13f14416a4
5 changed files with 419 additions and 75 deletions

View File

@@ -30,14 +30,53 @@ class TeamController
public function index(): void
{
$userId = (int) Session::get('user_id');
$teams = $this->teamModel->findByCreator($userId);
$search = $_GET['search'] ?? '';
if ($search !== '') {
$teams = $this->teamModel->findByCreator($userId);
$teams = array_filter($teams, function ($team) use ($search) {
$s = mb_strtolower($search);
return mb_strpos(mb_strtolower($team['name'] ?? ''), $s) !== false
|| mb_strpos(mb_strtolower($team['description'] ?? ''), $s) !== false;
});
} else {
$teams = $this->teamModel->findByCreator($userId);
}
$this->view->display('teams.index', [
'title' => 'Teams - ServerManager',
'teams' => $teams,
'search' => $search,
]);
}
public function searchUsers(): void
{
$q = $_GET['q'] ?? '';
if (mb_strlen($q) < 2) {
$this->view->json(['users' => []]);
return;
}
$userModel = new User();
$allUsers = $userModel->getAll(1, 999);
$filtered = array_filter($allUsers['data'], function ($u) use ($q) {
$s = mb_strtolower($q);
return mb_strpos(mb_strtolower($u['username'] ?? ''), $s) !== false
|| mb_strpos(mb_strtolower($u['email'] ?? ''), $s) !== false;
});
$results = array_map(function ($u) {
return [
'id' => (int) $u['id'],
'username' => $u['username'],
'email' => $u['email'],
];
}, array_slice(array_values($filtered), 0, 20));
$this->view->json(['users' => $results]);
}
public function create(): void
{
$this->view->display('teams.create', [