feat(user): add CreateUser button&page

This commit is contained in:
Vyacheslav1557 2025-02-25 23:04:08 +05:00
parent 9c7c6e9a58
commit b515ae3e67
6 changed files with 136 additions and 1 deletions

View file

@ -0,0 +1 @@
export {NewUserPage as default, generateMetadata} from "@/plain-pages/new-user";

View file

@ -0,0 +1 @@
export {NewUserPage, generateMetadata} from "./page";

View file

@ -0,0 +1,19 @@
"use server";
import {ClientPage} from "./ui";
import {Metadata} from "next";
const generateMetadata = async (): Promise<Metadata> => {
return {
title: 'Добавить пользователя',
description: '',
};
}
const Page = async () => {
return (
<ClientPage/>
)
}
export {Page as NewUserPage, generateMetadata};

View file

@ -0,0 +1,85 @@
"use client";
import {AppShell, AppShellHeader, AppShellMain, Button, PasswordInput, Stack, TextInput, Title} from "@mantine/core";
import {Header} from "@/components/header";
import React from "react";
import {useForm} from "@mantine/form";
import {useRouter} from "next/navigation";
import {useMutation} from "@tanstack/react-query";
import {CreateUser, Credentials} from "@/shared/api";
import {CreateUserResponse} from "../../../proto/user/v1/api";
const Page = () => {
const router = useRouter();
const form = useForm({
initialValues: {
username: "",
password: ""
},
});
const mutation = useMutation({
mutationFn: async (credentials: Credentials) => {
return await CreateUser(credentials)
},
onSuccess: async (data: CreateUserResponse) => {
await router.push(`/users/${data.id}`)
},
onError: (error) => {
form.clearErrors();
form.setFieldError("username", "Что-то пошло не так. Попробуйте позже.")
},
retry: false
});
const onSubmit = (event) => {
event.preventDefault()
mutation.mutate(form.getValues())
}
return (
<AppShell header={{height: 70}}>
<AppShellHeader>
<Header/>
</AppShellHeader>
<AppShellMain>
<form
onSubmit={onSubmit}
>
<Stack
align="center"
justify="center"
w="fit-content"
m="auto"
mt="5%"
p="md"
style={{color: "var(--mantine-color-bright)"}}
>
<Title>Добавить пользователя</Title>
<Stack w="100%" gap="0" align="center">
<TextInput
label="Username"
placeholder="Username"
key={form.key('username')}
w="250"
{...form.getInputProps('username')}
/>
<PasswordInput
label="Пароль"
placeholder="Пароль"
w="250"
key={form.key('password')}
{...form.getInputProps('password')}
/>
</Stack>
<Button type="submit" loading={mutation.isPending}>Добавить</Button>
</Stack>
</form>
</AppShellMain>
</AppShell>
);
};
export {Page as ClientPage};

View file

@ -6,6 +6,7 @@ import {
AppShellAside,
AppShellHeader,
AppShellMain,
Button,
Pagination,
Stack,
Table,
@ -99,6 +100,9 @@ const ClientPage = (props: Props) => {
<AppShellAside withBorder={false} px="16">
<Stack pt="16">
<TextInput placeholder="Поиск"/>
<Button component={Link} href="/users/new">
Добавить пользователя
</Button>
</Stack>
</AppShellAside>
</AppShell>

View file

@ -5,7 +5,7 @@ import {decode} from "jsonwebtoken";
import {cookies} from "next/headers";
import {authApi} from "./config";
type Credentials = {
export type Credentials = {
username: string,
password: string
}
@ -163,6 +163,7 @@ export const GetMe = async () => {
if (session === undefined) {
throw new Error("Session id not found");
// redirect("/login");
}
const options: AxiosRequestConfig = {
@ -173,6 +174,10 @@ export const GetMe = async () => {
const token = new JWTWithPermissions(decode(session.value) as JWT);
// if (token.exp < Date.now() / 1000) {
// redirect("/login");
// }
const response = await authApi.getUser(token.user_id, options);
return response.data;
@ -195,5 +200,25 @@ export const GetUsers = async (page: number, pageSize: number) => {
const response = await authApi.listUsers(page, pageSize, options);
return response.data;
}
export const CreateUser = async (credentials: Credentials) => {
const cookieStore = await cookies();
const session = cookieStore.get(CookieName);
if (session === undefined) {
throw new Error("Session id not found");
}
const options: AxiosRequestConfig = {
headers: {
'Authorization': "Bearer " + session.value
}
};
const response = await authApi.createUser(credentials, options);
return response.data;
}