Some checks failed
Build and Deploy React Package / build-and-publish (push) Failing after 1m38s
261 lines
8.2 KiB
TypeScript
261 lines
8.2 KiB
TypeScript
import {
|
||
Avatar,
|
||
Card,
|
||
MultiSelect,
|
||
Pill,
|
||
Stack,
|
||
Text,
|
||
UnstyledButton,
|
||
} from "@mantine/core";
|
||
import {
|
||
IconCancel,
|
||
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"
|
||
className="TeamMemberCard"
|
||
key={props.member.user.keycloak_id}
|
||
>
|
||
<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}
|
||
onChange={(value) => {
|
||
set_selected_permissions(value);
|
||
}}
|
||
/>
|
||
)}
|
||
</div>
|
||
</Stack>
|
||
</Card.Section>
|
||
<Card.Section
|
||
inheritPadding
|
||
px="md"
|
||
style={{
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
}}
|
||
>
|
||
<UnstyledButton
|
||
onClick={(e: Event) => {
|
||
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,
|
||
),
|
||
],
|
||
});
|
||
})
|
||
.catch(() => {
|
||
notifications.show({
|
||
radius: "md",
|
||
title: "Пользователя не получилось удалить",
|
||
message: "",
|
||
color: "red",
|
||
icon: <IconCancel />,
|
||
style: { paddingLeft: "5px" },
|
||
});
|
||
});
|
||
}}
|
||
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 + "Z").toLocaleDateString("ru")}
|
||
</Text>
|
||
<Text size="sm" style={{ textAlign: "right" }}>
|
||
{new Date(props.member.joined_at + "Z").toLocaleTimeString("ru")}
|
||
</Text>
|
||
</div>
|
||
</Stack>
|
||
</Card.Section>
|
||
</Card>
|
||
);
|
||
}
|
||
|
||
export default TeamMemberCard;
|