feat: add accounts table

This commit is contained in:
Vladislav Syrochkin 2025-06-24 13:00:40 +05:00
parent 71ab39a03c
commit a3ee18f6fd
5 changed files with 130 additions and 8 deletions

View File

@ -1,3 +1,4 @@
import { useUserSelector } from '@/store/userStore';
import { Avatar } from 'antd'; import { Avatar } from 'antd';
import Title from 'antd/es/typography/Title'; import Title from 'antd/es/typography/Title';
@ -7,6 +8,7 @@ interface HeaderProps {
} }
export default function Header({ title, additionalContent }: HeaderProps) { export default function Header({ title, additionalContent }: HeaderProps) {
const user = useUserSelector();
return ( return (
<div <div
style={{ style={{
@ -46,7 +48,7 @@ export default function Header({ title, additionalContent }: HeaderProps) {
> >
<Avatar <Avatar
size={25.77} size={25.77}
src={`https://cdn-icons-png.flaticon.com/512/219/219986.png`} src={`https://gamma.heado.ru/go/ava?name=${user?.login}`}
/> />
</div> </div>
</div> </div>

View File

@ -37,6 +37,16 @@ i18n
addAccount: 'Add account', addAccount: 'Add account',
save: 'Save changes', save: 'Save changes',
newAccount: 'New account', newAccount: 'New account',
ACTIVE: 'Active',
DISABLED: 'Disabled',
BLOCKED: 'Blocked',
DELETED: 'Deleted',
OWNER: 'Owner',
ADMIN: 'Admin',
EDITOR: 'Editor',
VIEWER: 'Viewer',
nameLogin: 'Name, login',
createdAt: 'Created',
}, },
}, },
ru: { ru: {
@ -66,6 +76,16 @@ i18n
addAccount: 'Добавить аккаунт', addAccount: 'Добавить аккаунт',
save: 'Сохранить изменения', save: 'Сохранить изменения',
newAccount: 'Новая учетная запись', newAccount: 'Новая учетная запись',
ACTIVE: 'Активен',
DISABLED: 'Выключен',
BLOCKED: 'Заблокирован',
DELETED: 'Удален',
OWNER: 'Владелец',
ADMIN: 'Админ',
EDITOR: 'Редактор',
VIEWER: 'Наблюдатель',
nameLogin: 'Имя, Логин',
createdAt: 'Создано',
}, },
}, },
}, },

View File

@ -1,9 +1,12 @@
import { useState } from 'react'; import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { User } from '@/types/user'; import { AccountStatus, AllUser, AllUserResponse } from '@/types/user';
import Header from '@/components/Header'; import Header from '@/components/Header';
import ContentDrawer from '@/components/ContentDrawer'; import ContentDrawer from '@/components/ContentDrawer';
import UserCreate from '@/components/UserCreate'; import UserCreate from '@/components/UserCreate';
import { Avatar, Table } from 'antd';
import { TableProps } from 'antd/lib';
import { UserService } from '@/services/userService';
export default function AccountsPage() { export default function AccountsPage() {
const { t } = useTranslation(); const { t } = useTranslation();
@ -12,7 +15,93 @@ export default function AccountsPage() {
const showDrawer = () => setOpen(true); const showDrawer = () => setOpen(true);
const closeDrawer = () => setOpen(false); const closeDrawer = () => setOpen(false);
const [accounts, setAccounts] = useState<User[]>([]); const [accounts, setAccounts] = useState<AllUserResponse>({
amountCount: 0,
amountPages: 0,
users: [],
});
useEffect(() => {
async function getUsers() {
const data = await UserService.getUsers();
setAccounts(data);
}
getUsers();
}, []);
const statusColor = {
ACTIVE: '#27AE60',
DISABLED: '#606060',
BLOCKED: '#FF0000',
DELETED: '#B30000',
};
const columns: TableProps<AllUser>['columns'] = [
{
title: '#',
dataIndex: 'id',
key: 'id',
},
{
title: t('nameLogin'),
dataIndex: 'nameLogin',
key: 'nameLogin',
render: (text, record) => (
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
<div
style={{
height: '32px',
width: '32px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Avatar
size={32}
src={`https://gamma.heado.ru/go/ava?name=${record.login}`}
/>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div>{record.name}</div>
<div style={{ color: '#606060' }}>{record.email}</div>
</div>
</div>
),
},
{
title: 'E-mail',
dataIndex: 'email',
key: 'email',
},
{
title: t('tenant'),
dataIndex: 'bindTenantId',
key: 'tenant',
},
{
title: t('role'),
dataIndex: 'role',
key: 'role',
render: (text) => <div>{t(text)}</div>,
},
{
title: t('createdAt'),
dataIndex: 'createdAt',
key: 'createdAt',
},
{
title: t('status'),
dataIndex: 'status',
key: 'status',
render: (text) => (
<div style={{ color: statusColor[text as AccountStatus] }}>
{t(text)}
</div>
),
},
];
return ( return (
<> <>
@ -31,6 +120,12 @@ export default function AccountsPage() {
/> />
} }
/> />
<Table
columns={columns}
dataSource={accounts.users}
pagination={{ pageSize: 10, current: 1, total: accounts.amountCount }}
rowKey={'id'}
/>
<ContentDrawer open={open} closeDrawer={closeDrawer} type="create"> <ContentDrawer open={open} closeDrawer={closeDrawer} type="create">
<UserCreate /> <UserCreate />

View File

@ -1,5 +1,5 @@
import api from '@/api/api'; import api from '@/api/api';
import { User } from '@/types/user'; import { AllUserResponse, User } from '@/types/user';
export class UserService { export class UserService {
static async getProfile(): Promise<User> { static async getProfile(): Promise<User> {
@ -9,8 +9,8 @@ export class UserService {
return user; return user;
} }
static async getUsers(page: number = 1, limit: number = 10): Promise<any> { static async getUsers(page: number = 1, limit: number = 10): Promise<AllUserResponse> {
const users = api.getUsers(page, limit); const allUsers = api.getUsers(page, limit);
return users; return allUsers;
} }
} }

View File

@ -1,3 +1,8 @@
import { components } from './openapi-types'; import { components } from './openapi-types';
export type User = components['schemas']['User']; export type User = components['schemas']['User'];
export type AllUserResponse = components['schemas']['AllUserResponse'];
export type AllUser = components['schemas']['AllUser'];
export type AccountStatus = components['schemas']['AccountStatus'];
export type AccountRole = components['schemas']['AccountRole'];