diff options
| author | Fuwn <[email protected]> | 2026-01-24 13:09:50 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-01-24 13:09:50 +0000 |
| commit | 396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b (patch) | |
| tree | b9df4ca6a70db45cfffbae6fdd7252e20fb8e93c /src/app/(main)/admin/users/UsersTable.tsx | |
| download | umami-main.tar.xz umami-main.zip | |
Created from https://vercel.com/new
Diffstat (limited to 'src/app/(main)/admin/users/UsersTable.tsx')
| -rw-r--r-- | src/app/(main)/admin/users/UsersTable.tsx | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/app/(main)/admin/users/UsersTable.tsx b/src/app/(main)/admin/users/UsersTable.tsx new file mode 100644 index 0000000..9c10f3e --- /dev/null +++ b/src/app/(main)/admin/users/UsersTable.tsx @@ -0,0 +1,84 @@ +import { DataColumn, DataTable, Icon, MenuItem, Modal, Row, Text } from '@umami/react-zen'; +import Link from 'next/link'; +import { useState } from 'react'; +import { DateDistance } from '@/components/common/DateDistance'; +import { useMessages } from '@/components/hooks'; +import { Edit, Trash } from '@/components/icons'; +import { MenuButton } from '@/components/input/MenuButton'; +import { ROLES } from '@/lib/constants'; +import { UserDeleteForm } from './UserDeleteForm'; + +export function UsersTable({ + data = [], + showActions = true, +}: { + data: any[]; + showActions?: boolean; +}) { + const { formatMessage, labels } = useMessages(); + const [deleteUser, setDeleteUser] = useState(null); + + return ( + <> + <DataTable data={data}> + <DataColumn id="username" label={formatMessage(labels.username)} width="2fr"> + {(row: any) => <Link href={`/admin/users/${row.id}`}>{row.username}</Link>} + </DataColumn> + <DataColumn id="role" label={formatMessage(labels.role)}> + {(row: any) => + formatMessage( + labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown, + ) + } + </DataColumn> + <DataColumn id="websites" label={formatMessage(labels.websites)}> + {(row: any) => row._count.websites} + </DataColumn> + <DataColumn id="created" label={formatMessage(labels.created)}> + {(row: any) => <DateDistance date={new Date(row.createdAt)} />} + </DataColumn> + {showActions && ( + <DataColumn id="action" align="end" width="100px"> + {(row: any) => { + const { id } = row; + + return ( + <MenuButton> + <MenuItem href={`/admin/users/${id}`} data-test="link-button-edit"> + <Row alignItems="center" gap> + <Icon> + <Edit /> + </Icon> + <Text>{formatMessage(labels.edit)}</Text> + </Row> + </MenuItem> + <MenuItem + id="delete" + onAction={() => setDeleteUser(row)} + data-test="link-button-delete" + > + <Row alignItems="center" gap> + <Icon> + <Trash /> + </Icon> + <Text>{formatMessage(labels.delete)}</Text> + </Row> + </MenuItem> + </MenuButton> + ); + }} + </DataColumn> + )} + </DataTable> + <Modal isOpen={!!deleteUser}> + <UserDeleteForm + userId={deleteUser?.id} + username={deleteUser?.username} + onClose={() => { + setDeleteUser(null); + }} + /> + </Modal> + </> + ); +} |