Added Team mamagement with backend integration
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
import {
|
||||
Avatar,
|
||||
Card,
|
||||
MultiSelect,
|
||||
Pill,
|
||||
Stack,
|
||||
Text,
|
||||
UnstyledButton,
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconCheck,
|
||||
IconCrown,
|
||||
IconForbid,
|
||||
IconPencil,
|
||||
IconTrash,
|
||||
} from "@tabler/icons-react";
|
||||
import CustomButton from "Components/CustomButton/CustomButton";
|
||||
import type { Team, TeamMember } from "Types/Team/Team";
|
||||
import "./TeamMemberCard.css";
|
||||
import { useState } from "react";
|
||||
import { addMember, deleteMember } from "Api/QuantumBackend/TeamManagement";
|
||||
import { useTeamStore } from "Stores/TeamsStore";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
|
||||
function TeamMemberCard(props: { cur_team: Team; member: TeamMember }) {
|
||||
const { updateTeam } = useTeamStore();
|
||||
const [is_editing, set_is_editing] = useState<boolean>(false);
|
||||
const [selected_permissions, set_selected_permissions] = useState<string[]>(
|
||||
props.member.permissions,
|
||||
);
|
||||
|
||||
return (
|
||||
<Card padding="sm" withBorder orientation="horizontal">
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="xs"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
justifyContent:
|
||||
props.member.user.keycloak_id !=
|
||||
props.cur_team.creator.user.keycloak_id
|
||||
? "center"
|
||||
: "",
|
||||
}}
|
||||
>
|
||||
{props.member.user.keycloak_id ==
|
||||
props.cur_team.creator.user.keycloak_id && <IconCrown />}
|
||||
<Avatar radius="xl" src={props.member.user.profile_picture_path} />
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
withBorder
|
||||
inheritPadding
|
||||
px="xs"
|
||||
style={{ width: "250px" }}
|
||||
>
|
||||
<Stack>
|
||||
<Text size="xl">{props.member.user.username}</Text>
|
||||
<Text size="md">{props.member.user.email}</Text>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="md"
|
||||
withBorder
|
||||
style={{
|
||||
display: "flex",
|
||||
flexGrow: 1,
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Stack>
|
||||
<div style={{ display: "flex", gap: "20px" }}>
|
||||
<Text size="md">Разрешения: </Text>
|
||||
|
||||
{props.member.user.keycloak_id !=
|
||||
props.cur_team.creator.user.keycloak_id &&
|
||||
(is_editing ? (
|
||||
<div style={{ display: "flex", gap: "10px" }}>
|
||||
<CustomButton
|
||||
style="outline"
|
||||
text="Сохранить"
|
||||
textSize="sm"
|
||||
icon={<IconPencil size={15} />}
|
||||
onClick={() => {
|
||||
addMember({
|
||||
team_id: props.cur_team.id,
|
||||
user_id: props.member.user.keycloak_id,
|
||||
permissions: selected_permissions,
|
||||
})
|
||||
.then((member) => {
|
||||
if (member) {
|
||||
updateTeam(props.cur_team.id, {
|
||||
members: [
|
||||
...props.cur_team.members.filter(
|
||||
(member) =>
|
||||
member.user.keycloak_id !=
|
||||
props.member.user.keycloak_id,
|
||||
),
|
||||
member,
|
||||
],
|
||||
});
|
||||
set_is_editing(false);
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
title: "Права изменены успешно",
|
||||
message: "",
|
||||
icon: <IconCheck />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
title: "Ошибка изменения прав",
|
||||
message: "",
|
||||
color: "red",
|
||||
icon: <IconForbid />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<CustomButton
|
||||
style="outline"
|
||||
text="Отменить"
|
||||
color="red"
|
||||
textSize="sm"
|
||||
icon={<IconPencil size={15} />}
|
||||
onClick={() => {
|
||||
set_is_editing(false);
|
||||
set_selected_permissions(props.member.permissions);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<CustomButton
|
||||
style="outline"
|
||||
text="Изменить"
|
||||
textSize="sm"
|
||||
icon={<IconPencil size={15} />}
|
||||
onClick={() => {
|
||||
set_is_editing(true);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
gap: "10px",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
{!is_editing ? (
|
||||
props.member.permissions.map((perm) => (
|
||||
<Pill className="TeamPill">{perm}</Pill>
|
||||
))
|
||||
) : (
|
||||
<MultiSelect
|
||||
value={selected_permissions}
|
||||
label=""
|
||||
placeholder="Выберите разрешения"
|
||||
searchable
|
||||
data={props.cur_team.creator.permissions}
|
||||
classNames={{ input: "MantineInput" }}
|
||||
onChange={(value) => {
|
||||
set_selected_permissions(value);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="md"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<UnstyledButton
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
deleteMember({
|
||||
team_id: props.cur_team.id,
|
||||
user_id: props.member.user.keycloak_id,
|
||||
}).then(() => {
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
title: "Пользователь удален успешно",
|
||||
message: "",
|
||||
icon: <IconCheck />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
updateTeam(props.cur_team.id, {
|
||||
members: [
|
||||
...props.cur_team.members.filter(
|
||||
(member) =>
|
||||
member.user.keycloak_id != props.member.user.keycloak_id,
|
||||
),
|
||||
],
|
||||
});
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
width: "20px",
|
||||
alignSelf: "flex-end",
|
||||
}}
|
||||
>
|
||||
<IconTrash size={20} />
|
||||
</UnstyledButton>
|
||||
<Stack gap={"5px"}>
|
||||
<Text style={{ alignSelf: "flex-end" }}>Добавлен:</Text>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: "5px",
|
||||
}}
|
||||
>
|
||||
<Text size="sm" style={{ textAlign: "right" }}>
|
||||
{new Date(props.member.joined_at).toLocaleDateString("ru")}
|
||||
</Text>
|
||||
<Text size="sm" style={{ textAlign: "right" }}>
|
||||
{new Date(props.member.joined_at).toLocaleTimeString("ru")}
|
||||
</Text>
|
||||
</div>
|
||||
</Stack>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default TeamMemberCard;
|
||||
Reference in New Issue
Block a user