F: Rework users API

This commit is contained in:
Ivan 2025-02-22 19:21:10 +03:00
parent 21269a1072
commit c5238bf1a0
6 changed files with 47 additions and 49 deletions

View File

@ -1,12 +1,18 @@
import { queryOptions } from '@tanstack/react-query';
import { z } from 'zod';
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS, KEYS } from '@/backend/configuration';
import { infoMsg } from '@/utils/labels';
import { type IUserInfo, type IUserProfile } from '../models/user';
import { type IUpdateProfileDTO, type IUserSignupDTO } from './types';
import {
type IUpdateProfileDTO,
type IUserInfo,
type IUserProfile,
type IUserSignupDTO,
schemaUserInfo,
schemaUserProfile
} from './types';
export const usersApi = {
baseKey: KEYS.users,
@ -17,6 +23,7 @@ export const usersApi = {
staleTime: DELAYS.staleMedium,
queryFn: meta =>
axiosGet<IUserInfo[]>({
schema: z.array(schemaUserInfo),
endpoint: '/users/api/active-users',
options: { signal: meta.signal }
})
@ -27,6 +34,7 @@ export const usersApi = {
staleTime: DELAYS.staleShort,
queryFn: meta =>
axiosGet<IUserProfile>({
schema: schemaUserProfile,
endpoint: '/users/api/profile',
options: { signal: meta.signal }
})
@ -34,6 +42,7 @@ export const usersApi = {
signup: (data: IUserSignupDTO) =>
axiosPost<IUserSignupDTO, IUserProfile>({
schema: schemaUserProfile,
endpoint: '/users/api/signup',
request: {
data: data,
@ -43,6 +52,7 @@ export const usersApi = {
updateProfile: (data: IUpdateProfileDTO) =>
axiosPatch<IUpdateProfileDTO, IUserProfile>({
schema: schemaUserProfile,
endpoint: '/users/api/profile',
request: {
data: data,

View File

@ -4,8 +4,37 @@ import { patterns } from '@/utils/constants';
import { errorMsg } from '@/utils/labels';
/**
* Represents signup data, used to create new users.
* Represents user detailed information.
* Some information should only be accessible to authorized users
*/
export type IUser = z.infer<typeof schemaUser>;
/** Represents user profile for viewing and editing {@link IUser}. */
export type IUserProfile = z.infer<typeof schemaUserProfile>;
/** Represents user reference information. */
export type IUserInfo = z.infer<typeof schemaUserInfo>;
/** Represents signup data, used to create new users. */
export type IUserSignupDTO = z.infer<typeof schemaUserSignup>;
/** Represents user data, intended to update user profile in persistent storage. */
export type IUpdateProfileDTO = z.infer<typeof schemaUpdateProfile>;
// ========= SCHEMAS ========
export const schemaUser = z.object({
id: z.coerce.number(),
username: z.string().nonempty(errorMsg.requiredField),
is_staff: z.boolean(),
email: z.string().email(errorMsg.emailField),
first_name: z.string(),
last_name: z.string()
});
export const schemaUserProfile = schemaUser.omit({ is_staff: true });
export const schemaUserInfo = schemaUser.omit({ username: true, email: true, is_staff: true });
export const schemaUserSignup = z
.object({
username: z.string().nonempty(errorMsg.requiredField).regex(RegExp(patterns.login), errorMsg.loginFormat),
@ -18,21 +47,8 @@ export const schemaUserSignup = z
})
.refine(schema => schema.password === schema.password2, { path: ['password2'], message: errorMsg.passwordsMismatch });
/**
* Represents signup data, used to create new users.
*/
export type IUserSignupDTO = z.infer<typeof schemaUserSignup>;
/**
* Represents user data, intended to update user profile in persistent storage.
*/
export const schemaUpdateProfile = z.object({
email: z.string().email(errorMsg.emailField),
first_name: z.string(),
last_name: z.string()
});
/**
* Represents user data, intended to update user profile in persistent storage.
*/
export type IUpdateProfileDTO = z.infer<typeof schemaUpdateProfile>;

View File

@ -4,7 +4,7 @@ import { MiniButton } from '@/components/Control';
import { createColumnHelper, DataTable } from '@/components/DataTable';
import { IconRemove } from '@/components/Icons';
import { type IUserInfo } from '../models/user';
import { type IUserInfo } from '../backend/types';
interface TableUsersProps {
items: IUserInfo[];

View File

@ -1,26 +0,0 @@
/**
* Module: Models for Users.
*/
/**
* Represents user detailed information.
* Some information should only be accessible to authorized users
*/
export interface IUser {
id: number;
username: string;
is_staff: boolean;
email: string;
first_name: string;
last_name: string;
}
/**
* Represents user profile for viewing and editing {@link IUser}.
*/
export interface IUserProfile extends Omit<IUser, 'is_staff'> {}
/**
* Represents user reference information.
*/
export interface IUserInfo extends Omit<IUserProfile, 'email' | 'username'> {}

View File

@ -4,7 +4,7 @@
import { TextMatcher } from '@/utils/utils';
import { type IUserInfo } from './user';
import { type IUserInfo } from '../backend/types';
/**
* Checks if a given target {@link IConstituenta} matches the specified query using the provided matching mode.

View File

@ -5,7 +5,7 @@ import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { urls, useBlockNavigation, useConceptNavigation } from '@/app';
import { urls, useConceptNavigation } from '@/app';
import { HelpTopic } from '@/features/help';
import { isAxiosError } from '@/backend/apiTransport';
@ -30,13 +30,11 @@ export function FormSignup() {
register,
handleSubmit,
clearErrors,
formState: { errors, isDirty }
formState: { errors }
} = useForm<IUserSignupDTO>({
resolver: zodResolver(schemaUserSignup)
});
useBlockNavigation(isDirty);
function resetErrors() {
clearServerError();
clearErrors();