diff --git a/frontend/src/pages/GroupPage.tsx b/frontend/src/pages/GroupPage.tsx index 8ef89ad..9ded3a4 100644 --- a/frontend/src/pages/GroupPage.tsx +++ b/frontend/src/pages/GroupPage.tsx @@ -1,14 +1,25 @@ +import { UserPlus } from "lucide-react"; +import { useState } from "react"; import { useNavigate } from "react-router-dom"; +import { ApiError } from "../api/client"; import { CreateGroupForm } from "../components/CreateGroupForm"; import { GroupInvitations } from "../components/GroupInvitations"; import { GroupSwitcher } from "../components/GroupSwitcher"; import { Leaderboard } from "../components/Leaderboard"; import { MatchListView } from "../components/MatchList"; import { Spinner } from "../components/Spinner"; +import { MAX_GROUP_SIZE } from "../domain/constants"; import { formatDate } from "../domain/format"; +import { useToast } from "../context/ToastContext"; import { useMe } from "../hooks/auth"; -import { useGroup, useGroupMatches, useGroupStats } from "../hooks/groups"; +import { + useGroup, + useGroupMatches, + useGroupMembers, + useGroupStats, + useInviteMember, +} from "../hooks/groups"; export function GroupPage() { const { data: me, isLoading } = useMe(); @@ -18,9 +29,25 @@ export function GroupPage() { const { data: group } = useGroup(groupId); const { data: stats } = useGroupStats(groupId); const { data: matches } = useGroupMatches(groupId); + const { data: members } = useGroupMembers(groupId); + const inviteMember = useInviteMember(); + const toast = useToast(); + const [newNick, setNewNick] = useState(""); if (isLoading) return ; + const invite = async () => { + const nick = newNick.trim(); + if (!nick || !groupId) return; + try { + await inviteMember.mutateAsync({ groupId, nickname: nick }); + setNewNick(""); + toast.show("Приглашение отправлено"); + } catch (e) { + toast.show(e instanceof ApiError ? e.message : "Ошибка"); + } + }; + if (!groupId) { return (
@@ -57,7 +84,7 @@ export function GroupPage() {
-

Статистика игроков

+

Список игроков

{stats && ( )} + {/* Приглашение нового игрока — здесь, рядом со списком (не в настройках). */} + {(members ?? []).length >= MAX_GROUP_SIZE ? ( +

+ Достигнут максимум участников ({MAX_GROUP_SIZE}). +

+ ) : ( +
+ setNewNick(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") invite(); + }} + /> + +
+ )}
diff --git a/frontend/src/pages/GroupSettingsPage.tsx b/frontend/src/pages/GroupSettingsPage.tsx index be2b233..f4d7f67 100644 --- a/frontend/src/pages/GroupSettingsPage.tsx +++ b/frontend/src/pages/GroupSettingsPage.tsx @@ -1,4 +1,4 @@ -import { Trash2, UserPlus } from "lucide-react"; +import { Trash2 } from "lucide-react"; import { useEffect, useState } from "react"; import { ApiError } from "../api/client"; @@ -9,7 +9,7 @@ import { Switch } from "../components/Switch"; import { MAX_GROUP_SIZE } from "../domain/constants"; import { useToast } from "../context/ToastContext"; import { useMe } from "../hooks/auth"; -import { useGroup, useGroupMembers, useInviteMember, useRemoveMember, useSetGroupExpansions } from "../hooks/groups"; +import { useGroup, useGroupMembers, useRemoveMember, useSetGroupExpansions } from "../hooks/groups"; import { useExpansions } from "../hooks/reference"; export function GroupSettingsPage() { @@ -19,12 +19,10 @@ export function GroupSettingsPage() { const { data: expansions } = useExpansions(); const { data: members } = useGroupMembers(groupId); const setExpansions = useSetGroupExpansions(groupId ?? 0); - const inviteMember = useInviteMember(); const removeMember = useRemoveMember(groupId ?? 0); const toast = useToast(); const [selected, setSelected] = useState>(new Set()); - const [newNick, setNewNick] = useState(""); const [removeTarget, setRemoveTarget] = useState<{ userId: number; nickname: string } | null>(null); useEffect(() => { @@ -51,18 +49,6 @@ export function GroupSettingsPage() { } }; - const add = async () => { - const nick = newNick.trim(); - if (!nick) return; - try { - await inviteMember.mutateAsync({ groupId: group.id, nickname: nick }); - setNewNick(""); - toast.show("Приглашение отправлено"); - } catch (e) { - toast.show(e instanceof ApiError ? e.message : "Ошибка"); - } - }; - const remove = async (userId: number) => { try { await removeMember.mutateAsync(userId); @@ -99,22 +85,8 @@ export function GroupSettingsPage() {
+ {/* Приглашение нового игрока — на странице группы («Список игроков»). */}

Участники ({(members ?? []).length}/{MAX_GROUP_SIZE})

- {isOwner && (members ?? []).length >= MAX_GROUP_SIZE && ( -

Достигнут максимум участников ({MAX_GROUP_SIZE}).

- )} - {isOwner && (members ?? []).length < MAX_GROUP_SIZE && ( -
- setNewNick(e.target.value)} - /> - -
- )}
{(members ?? []).map((m) => (