mirror of
https://github.com/serty2005/rmser.git
synced 2026-02-04 19:02:33 -06:00
0302-отрефакторил в нормальный вид на мобилу и десктоп
сразу выкинул пути в импортах и добавил алиас для корня
This commit is contained in:
196
rmser-view/src/modules/mobile/components/settings/TeamList.tsx
Normal file
196
rmser-view/src/modules/mobile/components/settings/TeamList.tsx
Normal file
@@ -0,0 +1,196 @@
|
||||
import React from "react";
|
||||
import {
|
||||
List,
|
||||
Avatar,
|
||||
Tag,
|
||||
Button,
|
||||
Select,
|
||||
Popconfirm,
|
||||
message,
|
||||
Spin,
|
||||
Alert,
|
||||
Typography,
|
||||
} from "antd";
|
||||
import { DeleteOutlined, UserOutlined } from "@ant-design/icons";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { api } from "@/shared/api";
|
||||
import type { ServerUser, UserRole } from "@/shared/types";
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
interface Props {
|
||||
currentUserRole: UserRole;
|
||||
}
|
||||
|
||||
export const TeamList: React.FC<Props> = ({ currentUserRole }) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const {
|
||||
data: users,
|
||||
isLoading,
|
||||
isError,
|
||||
} = useQuery({
|
||||
queryKey: ["serverUsers"],
|
||||
queryFn: api.getUsers,
|
||||
});
|
||||
|
||||
const updateRoleMutation = useMutation({
|
||||
mutationFn: ({ userId, newRole }: { userId: string; newRole: UserRole }) =>
|
||||
api.updateUserRole(userId, newRole),
|
||||
onSuccess: () => {
|
||||
message.success("Роль пользователя обновлена");
|
||||
queryClient.invalidateQueries({ queryKey: ["serverUsers"] });
|
||||
},
|
||||
onError: () => {
|
||||
message.error("Не удалось изменить роль");
|
||||
},
|
||||
});
|
||||
|
||||
const removeUserMutation = useMutation({
|
||||
mutationFn: (userId: string) => api.removeUser(userId),
|
||||
onSuccess: () => {
|
||||
message.success("Пользователь удален из команды");
|
||||
queryClient.invalidateQueries({ queryKey: ["serverUsers"] });
|
||||
},
|
||||
onError: () => {
|
||||
message.error("Не удалось удалить пользователя");
|
||||
},
|
||||
});
|
||||
|
||||
const getRoleColor = (role: UserRole) => {
|
||||
switch (role) {
|
||||
case "OWNER":
|
||||
return "gold";
|
||||
case "ADMIN":
|
||||
return "blue";
|
||||
case "OPERATOR":
|
||||
return "default";
|
||||
default:
|
||||
return "default";
|
||||
}
|
||||
};
|
||||
|
||||
const getRoleName = (role: UserRole) => {
|
||||
switch (role) {
|
||||
case "OWNER":
|
||||
return "Владелец";
|
||||
case "ADMIN":
|
||||
return "Админ";
|
||||
case "OPERATOR":
|
||||
return "Оператор";
|
||||
default:
|
||||
return role;
|
||||
}
|
||||
};
|
||||
|
||||
const canDelete = (targetUser: ServerUser) => {
|
||||
if (targetUser.is_me) return false;
|
||||
if (targetUser.role === "OWNER") return false;
|
||||
if (currentUserRole === "ADMIN" && targetUser.role === "ADMIN")
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div style={{ textAlign: "center", padding: 20 }}>
|
||||
<Spin />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
return <Alert type="error" message="Не удалось загрузить список команды" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Alert
|
||||
type="info"
|
||||
showIcon
|
||||
style={{ marginBottom: 16 }}
|
||||
message="Приглашение сотрудников"
|
||||
description="Чтобы добавить сотрудника, отправьте ему ссылку-приглашение."
|
||||
/>
|
||||
<List
|
||||
itemLayout="horizontal"
|
||||
dataSource={users || []}
|
||||
renderItem={(user) => (
|
||||
<List.Item
|
||||
actions={[
|
||||
currentUserRole === "OWNER" && !user.is_me ? (
|
||||
<Select
|
||||
key="role-select"
|
||||
defaultValue={user.role}
|
||||
size="small"
|
||||
style={{ width: 110 }}
|
||||
disabled={updateRoleMutation.isPending}
|
||||
onChange={(val) =>
|
||||
updateRoleMutation.mutate({
|
||||
userId: user.user_id,
|
||||
newRole: val,
|
||||
})
|
||||
}
|
||||
options={[
|
||||
{ value: "ADMIN", label: "Админ" },
|
||||
{ value: "OPERATOR", label: "Оператор" },
|
||||
]}
|
||||
/>
|
||||
) : (
|
||||
<Tag key="role-tag" color={getRoleColor(user.role)}>
|
||||
{getRoleName(user.role)}
|
||||
</Tag>
|
||||
),
|
||||
<Popconfirm
|
||||
key="delete"
|
||||
title="Закрыть доступ?"
|
||||
description={`Вы уверены, что хотите удалить ${user.first_name}?`}
|
||||
onConfirm={() => removeUserMutation.mutate(user.user_id)}
|
||||
disabled={!canDelete(user)}
|
||||
okText="Да"
|
||||
cancelText="Нет"
|
||||
>
|
||||
<Button
|
||||
danger
|
||||
type="text"
|
||||
icon={<DeleteOutlined />}
|
||||
disabled={!canDelete(user) || removeUserMutation.isPending}
|
||||
/>
|
||||
</Popconfirm>,
|
||||
]}
|
||||
>
|
||||
<List.Item.Meta
|
||||
avatar={
|
||||
<Avatar src={user.photo_url} icon={<UserOutlined />}>
|
||||
{user.first_name?.[0]}
|
||||
</Avatar>
|
||||
}
|
||||
title={
|
||||
<span>
|
||||
{user.first_name} {user.last_name}{" "}
|
||||
{user.is_me && <Text type="secondary">(Вы)</Text>}
|
||||
</span>
|
||||
}
|
||||
description={
|
||||
user.username ? (
|
||||
<a
|
||||
href={`https://t.me/${user.username}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ fontSize: 12 }}
|
||||
>
|
||||
@{user.username}
|
||||
</a>
|
||||
) : (
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
Нет username
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user