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/teams | |
| download | umami-main.tar.xz umami-main.zip | |
Created from https://vercel.com/new
Diffstat (limited to 'src/app/(main)/admin/teams')
| -rw-r--r-- | src/app/(main)/admin/teams/AdminTeamsDataTable.tsx | 19 | ||||
| -rw-r--r-- | src/app/(main)/admin/teams/AdminTeamsPage.tsx | 19 | ||||
| -rw-r--r-- | src/app/(main)/admin/teams/AdminTeamsTable.tsx | 86 | ||||
| -rw-r--r-- | src/app/(main)/admin/teams/[teamId]/AdminTeamPage.tsx | 11 | ||||
| -rw-r--r-- | src/app/(main)/admin/teams/[teamId]/page.tsx | 12 | ||||
| -rw-r--r-- | src/app/(main)/admin/teams/page.tsx | 9 |
6 files changed, 156 insertions, 0 deletions
diff --git a/src/app/(main)/admin/teams/AdminTeamsDataTable.tsx b/src/app/(main)/admin/teams/AdminTeamsDataTable.tsx new file mode 100644 index 0000000..7da8531 --- /dev/null +++ b/src/app/(main)/admin/teams/AdminTeamsDataTable.tsx @@ -0,0 +1,19 @@ +import type { ReactNode } from 'react'; +import { DataGrid } from '@/components/common/DataGrid'; +import { useTeamsQuery } from '@/components/hooks'; +import { AdminTeamsTable } from './AdminTeamsTable'; + +export function AdminTeamsDataTable({ + showActions, +}: { + showActions?: boolean; + children?: ReactNode; +}) { + const queryResult = useTeamsQuery(); + + return ( + <DataGrid query={queryResult} allowSearch={true}> + {({ data }) => <AdminTeamsTable data={data} showActions={showActions} />} + </DataGrid> + ); +} diff --git a/src/app/(main)/admin/teams/AdminTeamsPage.tsx b/src/app/(main)/admin/teams/AdminTeamsPage.tsx new file mode 100644 index 0000000..41e6f4a --- /dev/null +++ b/src/app/(main)/admin/teams/AdminTeamsPage.tsx @@ -0,0 +1,19 @@ +'use client'; +import { Column } from '@umami/react-zen'; +import { PageHeader } from '@/components/common/PageHeader'; +import { Panel } from '@/components/common/Panel'; +import { useMessages } from '@/components/hooks'; +import { AdminTeamsDataTable } from './AdminTeamsDataTable'; + +export function AdminTeamsPage() { + const { formatMessage, labels } = useMessages(); + + return ( + <Column gap="6" margin="2"> + <PageHeader title={formatMessage(labels.teams)} /> + <Panel> + <AdminTeamsDataTable /> + </Panel> + </Column> + ); +} diff --git a/src/app/(main)/admin/teams/AdminTeamsTable.tsx b/src/app/(main)/admin/teams/AdminTeamsTable.tsx new file mode 100644 index 0000000..9f2abd5 --- /dev/null +++ b/src/app/(main)/admin/teams/AdminTeamsTable.tsx @@ -0,0 +1,86 @@ +import { DataColumn, DataTable, Dialog, 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 { TeamDeleteForm } from '../../teams/[teamId]/TeamDeleteForm'; + +export function AdminTeamsTable({ + data = [], + showActions = true, +}: { + data: any[]; + showActions?: boolean; +}) { + const { formatMessage, labels } = useMessages(); + const [deleteTeam, setDeleteTeam] = useState(null); + + return ( + <> + <DataTable data={data}> + <DataColumn id="name" label={formatMessage(labels.name)} width="1fr"> + {(row: any) => <Link href={`/admin/teams/${row.id}`}>{row.name}</Link>} + </DataColumn> + <DataColumn id="websites" label={formatMessage(labels.members)} width="140px"> + {(row: any) => row?._count?.members} + </DataColumn> + <DataColumn id="members" label={formatMessage(labels.websites)} width="140px"> + {(row: any) => row?._count?.websites} + </DataColumn> + <DataColumn id="owner" label={formatMessage(labels.owner)}> + {(row: any) => { + const name = row?.members?.[0]?.user?.username; + + return ( + <Text title={name} truncate> + <Link href={`/admin/users/${row?.members?.[0]?.user?.id}`}>{name}</Link> + </Text> + ); + }} + </DataColumn> + <DataColumn id="created" label={formatMessage(labels.created)} width="160px"> + {(row: any) => <DateDistance date={new Date(row.createdAt)} />} + </DataColumn> + {showActions && ( + <DataColumn id="action" align="end" width="50px"> + {(row: any) => { + const { id } = row; + + return ( + <MenuButton> + <MenuItem href={`/admin/teams/${id}`} data-test="link-button-edit"> + <Row alignItems="center" gap> + <Icon> + <Edit /> + </Icon> + <Text>{formatMessage(labels.edit)}</Text> + </Row> + </MenuItem> + <MenuItem + id="delete" + onAction={() => setDeleteTeam(id)} + data-test="link-button-delete" + > + <Row alignItems="center" gap> + <Icon> + <Trash /> + </Icon> + <Text>{formatMessage(labels.delete)}</Text> + </Row> + </MenuItem> + </MenuButton> + ); + }} + </DataColumn> + )} + </DataTable> + <Modal isOpen={!!deleteTeam}> + <Dialog style={{ width: 400 }}> + <TeamDeleteForm teamId={deleteTeam} onClose={() => setDeleteTeam(null)} /> + </Dialog> + </Modal> + </> + ); +} diff --git a/src/app/(main)/admin/teams/[teamId]/AdminTeamPage.tsx b/src/app/(main)/admin/teams/[teamId]/AdminTeamPage.tsx new file mode 100644 index 0000000..2150197 --- /dev/null +++ b/src/app/(main)/admin/teams/[teamId]/AdminTeamPage.tsx @@ -0,0 +1,11 @@ +'use client'; +import { TeamSettings } from '@/app/(main)/teams/[teamId]/TeamSettings'; +import { TeamProvider } from '@/app/(main)/teams/TeamProvider'; + +export function AdminTeamPage({ teamId }: { teamId: string }) { + return ( + <TeamProvider teamId={teamId}> + <TeamSettings teamId={teamId} /> + </TeamProvider> + ); +} diff --git a/src/app/(main)/admin/teams/[teamId]/page.tsx b/src/app/(main)/admin/teams/[teamId]/page.tsx new file mode 100644 index 0000000..104766a --- /dev/null +++ b/src/app/(main)/admin/teams/[teamId]/page.tsx @@ -0,0 +1,12 @@ +import type { Metadata } from 'next'; +import { AdminTeamPage } from './AdminTeamPage'; + +export default async function ({ params }: { params: Promise<{ teamId: string }> }) { + const { teamId } = await params; + + return <AdminTeamPage teamId={teamId} />; +} + +export const metadata: Metadata = { + title: 'Team', +}; diff --git a/src/app/(main)/admin/teams/page.tsx b/src/app/(main)/admin/teams/page.tsx new file mode 100644 index 0000000..987f02b --- /dev/null +++ b/src/app/(main)/admin/teams/page.tsx @@ -0,0 +1,9 @@ +import type { Metadata } from 'next'; +import { AdminTeamsPage } from './AdminTeamsPage'; + +export default function () { + return <AdminTeamsPage />; +} +export const metadata: Metadata = { + title: 'Teams', +}; |