Add tRPC user query

This commit is contained in:
Manuel
2023-07-29 16:08:58 +02:00
parent 5c4e1a4bb8
commit e4e1f2e32e
4 changed files with 144 additions and 20 deletions

View File

@@ -14,6 +14,7 @@ import {
TextInput,
ThemeIcon,
UnstyledButton,
useMantineTheme,
} from '@mantine/core';
import {
IconAlertTriangle,
@@ -47,11 +48,12 @@ interface MainLayoutProps {
export const MainLayout = ({ children }: MainLayoutProps) => {
const { t } = useTranslation();
const { attributes } = usePackageAttributesStore();
const theme = useMantineTheme();
return (
<AppShell
styles={{
root: {
background: '#f1f1f1',
background: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[1],
},
}}
navbar={

View File

@@ -1,12 +1,98 @@
import { Title } from "@mantine/core";
import { MainLayout } from "~/components/layout/admin/main-admin.layout";
import {
ActionIcon,
Autocomplete,
Avatar,
Button,
Flex,
Group,
Pagination,
SegmentedControl,
Table,
Text,
Title,
} from '@mantine/core';
import { IconPlus, IconTrash } from '@tabler/icons-react';
import Head from 'next/head';
import { useState } from 'react';
import { MainLayout } from '~/components/layout/admin/main-admin.layout';
import { api } from '~/utils/api';
const ManageUsersPage = () => {
return (
<MainLayout>
<Title>Manage users</Title>
</MainLayout>
)
}
const { isLoading, data, fetchNextPage, fetchPreviousPage } = api.user.getAll.useInfiniteQuery(
{
limit: 10,
},
{
getNextPageParam: (lastPage) => lastPage.nextCursor,
}
);
export default ManageUsersPage;
const [activePage, _] = useState(1);
return (
<MainLayout>
<Head>
<title>Users Homarr</title>
</Head>
<Title mb="xl">Manage users</Title>
<Group position="apart" mb="md">
<SegmentedControl
data={[
{ label: 'Active', value: 'active' },
{ label: 'Inactive', value: 'inactive' },
]}
/>
<Flex columnGap={10}>
<Autocomplete
placeholder="Filter"
data={['React', 'Angular', 'Svelte', 'Vue']}
variant="filled"
/>
<Button leftIcon={<IconPlus size="1rem" />} variant="default">
Create
</Button>
</Flex>
</Group>
{data && (
<>
<Table mb="md" withBorder highlightOnHover>
<thead>
<tr>
<th>User</th>
</tr>
</thead>
<tbody>
{data.pages[0].users.map((user) => (
<tr>
<td>
<Group position="apart">
<Group spacing="xs">
<Avatar size="sm" />
<Text>{user.name}</Text>
</Group>
<Group>
<ActionIcon color="red" variant="light">
<IconTrash size="1rem" />
</ActionIcon>
</Group>
</Group>
</td>
</tr>
))}
</tbody>
</Table>
<Pagination
total={data.pages.length}
value={activePage}
onNextPage={fetchNextPage}
onPreviousPage={fetchPreviousPage}
/>
</>
)}
</MainLayout>
);
};
export default ManageUsersPage;

View File

@@ -1,12 +1,16 @@
import { Title } from "@mantine/core";
import { MainLayout } from "~/components/layout/admin/main-admin.layout";
import { Title } from '@mantine/core';
import { Head } from 'next/document';
import { MainLayout } from '~/components/layout/admin/main-admin.layout';
const ManageUserInvitesPage = () => {
return (
<MainLayout>
<Title>Manage user invites</Title>
</MainLayout>
)
}
return (
<MainLayout>
<Head>
<title>User invites Homarr</title>
</Head>
<Title>Manage user invites</Title>
</MainLayout>
);
};
export default ManageUserInvitesPage;
export default ManageUserInvitesPage;

View File

@@ -110,7 +110,7 @@ export const userRouter = createTRPCRouter({
},
});
}),
getWithSettings: protectedProcedure.query(async ({ ctx }) => {
getWithSettings: protectedProcedure.query(async ({ ctx, input }) => {
const user = await ctx.prisma.user.findUnique({
where: {
id: ctx.session?.user?.id,
@@ -133,4 +133,36 @@ export const userRouter = createTRPCRouter({
settings: user.settings,
};
}),
getAll: publicProcedure
.input(
z.object({
limit: z.number().min(1).max(100).nullish(),
cursor: z.number().nullish(),
})
)
.query(async ({ ctx, input }) => {
const limit = input.limit ?? 50;
const cursor = input.cursor;
const users = await ctx.prisma.user.findMany({
take: limit + 1, // get an extra item at the end which we'll use as next cursor
cursor: cursor ? { myCursor: cursor } : undefined,
});
let nextCursor: typeof cursor | undefined = undefined;
if (users.length > limit) {
const nextItem = users.pop();
nextCursor = nextItem!.myCursor;
}
return {
users: users.map((user) => ({
id: user.id,
name: user.name,
email: user.email,
emailVerified: user.emailVerified
})),
nextCursor,
};
}),
});