1bd21a85fe
Original task: Add a 7d/30d/90d range selector to the admin dashboard trend cards/chart and have /stats/admin accept a matching range parameter. Changes: - OpenAPI (lib/api-spec/openapi.yaml): added optional `range` query parameter (enum 7d|30d|90d, default 7d) to GET /stats/admin and refactored AdminStats fields to be range-agnostic — added `range` and `rangeDays`, renamed `*Last7Days`/`*Prev7Days` to `*InRange`/ `*PrevRange`. Regenerated api-client-react and api-zod. - API server (artifacts/api-server/src/routes/stats.ts): parses and validates the `range` param, computes range/prev-range windows generically, and returns daily series sized to rangeDays. - Admin UI (artifacts/teaboy-os/src/pages/admin.tsx): adds a segmented range selector at the top of the dashboard, passes the selected range into the stats query (with proper queryKey), and adapts the trend chart for denser ranges (skipped per-bar count text >14 days, every-Nth date label, month/day formatting for 30d/90d). - Locale files (en.json/ar.json): added range/prevRange labels, trends/rangeSelector strings, and *Ranged variants of summary keys. Old keys kept to avoid stale references. Verification: - pnpm typecheck passes across libs and artifacts. - e2e test (login as admin → toggle 7d/30d/90d → verify chart bar counts and aria-pressed state, plus API responses for each range) passes. Notes / deviations: - Had to (re)create the `app_opens` table in the dev DB and reset the seeded admin password hash to run the e2e test; both were preexisting environment drift unrelated to this task. - Followed up with: custom date range, persisting last-used range.
3160 lines
81 KiB
TypeScript
3160 lines
81 KiB
TypeScript
/**
|
|
* Generated by orval v8.5.3 🍺
|
|
* Do not edit manually.
|
|
* Api
|
|
* TeaBoy OS API specification
|
|
* OpenAPI spec version: 0.1.0
|
|
*/
|
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
import type {
|
|
MutationFunction,
|
|
QueryFunction,
|
|
QueryKey,
|
|
UseMutationOptions,
|
|
UseMutationResult,
|
|
UseQueryOptions,
|
|
UseQueryResult,
|
|
} from "@tanstack/react-query";
|
|
|
|
import type {
|
|
AdminStats,
|
|
App,
|
|
AppSettings,
|
|
AuthUser,
|
|
ConversationWithDetails,
|
|
CreateAppBody,
|
|
CreateConversationBody,
|
|
CreateServiceBody,
|
|
ErrorResponse,
|
|
GetAdminStatsParams,
|
|
HealthStatus,
|
|
HomeStats,
|
|
LoginBody,
|
|
MessageWithSender,
|
|
Notification,
|
|
RegisterBody,
|
|
RequestUploadUrlBody,
|
|
RequestUploadUrlResponse,
|
|
SendMessageBody,
|
|
Service,
|
|
ServiceCategory,
|
|
SuccessResponse,
|
|
UpdateAppBody,
|
|
UpdateAppSettingsBody,
|
|
UpdateLanguageBody,
|
|
UpdateMyAppOrderBody,
|
|
UpdateServiceBody,
|
|
UpdateUserBody,
|
|
UserProfile,
|
|
} from "./api.schemas";
|
|
|
|
import { customFetch } from "../custom-fetch";
|
|
import type { ErrorType, BodyType } from "../custom-fetch";
|
|
|
|
type AwaitedInput<T> = PromiseLike<T> | T;
|
|
|
|
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
|
|
|
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
|
|
|
/**
|
|
* @summary Health check
|
|
*/
|
|
export const getHealthCheckUrl = () => {
|
|
return `/api/healthz`;
|
|
};
|
|
|
|
export const healthCheck = async (
|
|
options?: RequestInit,
|
|
): Promise<HealthStatus> => {
|
|
return customFetch<HealthStatus>(getHealthCheckUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getHealthCheckQueryKey = () => {
|
|
return [`/api/healthz`] as const;
|
|
};
|
|
|
|
export const getHealthCheckQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof healthCheck>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof healthCheck>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getHealthCheckQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof healthCheck>>> = ({
|
|
signal,
|
|
}) => healthCheck({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof healthCheck>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type HealthCheckQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof healthCheck>>
|
|
>;
|
|
export type HealthCheckQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Health check
|
|
*/
|
|
|
|
export function useHealthCheck<
|
|
TData = Awaited<ReturnType<typeof healthCheck>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof healthCheck>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getHealthCheckQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Register a new user
|
|
*/
|
|
export const getRegisterUrl = () => {
|
|
return `/api/auth/register`;
|
|
};
|
|
|
|
export const register = async (
|
|
registerBody: RegisterBody,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getRegisterUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(registerBody),
|
|
});
|
|
};
|
|
|
|
export const getRegisterMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["register"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof register>>,
|
|
{ data: BodyType<RegisterBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return register(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type RegisterMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof register>>
|
|
>;
|
|
export type RegisterMutationBody = BodyType<RegisterBody>;
|
|
export type RegisterMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Register a new user
|
|
*/
|
|
export const useRegister = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getRegisterMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Login
|
|
*/
|
|
export const getLoginUrl = () => {
|
|
return `/api/auth/login`;
|
|
};
|
|
|
|
export const login = async (
|
|
loginBody: LoginBody,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getLoginUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(loginBody),
|
|
});
|
|
};
|
|
|
|
export const getLoginMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["login"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof login>>,
|
|
{ data: BodyType<LoginBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return login(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type LoginMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof login>>
|
|
>;
|
|
export type LoginMutationBody = BodyType<LoginBody>;
|
|
export type LoginMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Login
|
|
*/
|
|
export const useLogin = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getLoginMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Logout
|
|
*/
|
|
export const getLogoutUrl = () => {
|
|
return `/api/auth/logout`;
|
|
};
|
|
|
|
export const logout = async (
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getLogoutUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getLogoutMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["logout"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
void
|
|
> = () => {
|
|
return logout(requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type LogoutMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof logout>>
|
|
>;
|
|
|
|
export type LogoutMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Logout
|
|
*/
|
|
export const useLogout = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
return useMutation(getLogoutMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get current user
|
|
*/
|
|
export const getGetMeUrl = () => {
|
|
return `/api/auth/me`;
|
|
};
|
|
|
|
export const getMe = async (options?: RequestInit): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getGetMeUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetMeQueryKey = () => {
|
|
return [`/api/auth/me`] as const;
|
|
};
|
|
|
|
export const getGetMeQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getMe>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getMe>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetMeQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getMe>>> = ({
|
|
signal,
|
|
}) => getMe({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getMe>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetMeQueryResult = NonNullable<Awaited<ReturnType<typeof getMe>>>;
|
|
export type GetMeQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Get current user
|
|
*/
|
|
|
|
export function useGetMe<
|
|
TData = Awaited<ReturnType<typeof getMe>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getMe>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetMeQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update preferred language
|
|
*/
|
|
export const getUpdateLanguageUrl = () => {
|
|
return `/api/auth/me/language`;
|
|
};
|
|
|
|
export const updateLanguage = async (
|
|
updateLanguageBody: UpdateLanguageBody,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getUpdateLanguageUrl(), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateLanguageBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateLanguageMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateLanguage"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
{ data: BodyType<UpdateLanguageBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateLanguage(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateLanguageMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateLanguage>>
|
|
>;
|
|
export type UpdateLanguageMutationBody = BodyType<UpdateLanguageBody>;
|
|
export type UpdateLanguageMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update preferred language
|
|
*/
|
|
export const useUpdateLanguage = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateLanguageMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List all active apps
|
|
*/
|
|
export const getListAppsUrl = () => {
|
|
return `/api/apps`;
|
|
};
|
|
|
|
export const listApps = async (options?: RequestInit): Promise<App[]> => {
|
|
return customFetch<App[]>(getListAppsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListAppsQueryKey = () => {
|
|
return [`/api/apps`] as const;
|
|
};
|
|
|
|
export const getListAppsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listApps>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listApps>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListAppsQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listApps>>> = ({
|
|
signal,
|
|
}) => listApps({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listApps>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListAppsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listApps>>
|
|
>;
|
|
export type ListAppsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List all active apps
|
|
*/
|
|
|
|
export function useListApps<
|
|
TData = Awaited<ReturnType<typeof listApps>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listApps>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListAppsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a new app (admin)
|
|
*/
|
|
export const getCreateAppUrl = () => {
|
|
return `/api/apps`;
|
|
};
|
|
|
|
export const createApp = async (
|
|
createAppBody: CreateAppBody,
|
|
options?: RequestInit,
|
|
): Promise<App> => {
|
|
return customFetch<App>(getCreateAppUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createAppBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateAppMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createApp"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
{ data: BodyType<CreateAppBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createApp(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateAppMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createApp>>
|
|
>;
|
|
export type CreateAppMutationBody = BodyType<CreateAppBody>;
|
|
export type CreateAppMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Create a new app (admin)
|
|
*/
|
|
export const useCreateApp = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateAppMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get app by ID
|
|
*/
|
|
export const getGetAppUrl = (id: number) => {
|
|
return `/api/apps/${id}`;
|
|
};
|
|
|
|
export const getApp = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<App> => {
|
|
return customFetch<App>(getGetAppUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetAppQueryKey = (id: number) => {
|
|
return [`/api/apps/${id}`] as const;
|
|
};
|
|
|
|
export const getGetAppQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getApp>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getApp>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetAppQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getApp>>> = ({
|
|
signal,
|
|
}) => getApp(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<Awaited<ReturnType<typeof getApp>>, TError, TData> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
};
|
|
|
|
export type GetAppQueryResult = NonNullable<Awaited<ReturnType<typeof getApp>>>;
|
|
export type GetAppQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get app by ID
|
|
*/
|
|
|
|
export function useGetApp<
|
|
TData = Awaited<ReturnType<typeof getApp>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getApp>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAppQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update app (admin)
|
|
*/
|
|
export const getUpdateAppUrl = (id: number) => {
|
|
return `/api/apps/${id}`;
|
|
};
|
|
|
|
export const updateApp = async (
|
|
id: number,
|
|
updateAppBody: UpdateAppBody,
|
|
options?: RequestInit,
|
|
): Promise<App> => {
|
|
return customFetch<App>(getUpdateAppUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateAppBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateAppMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateApp"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
{ id: number; data: BodyType<UpdateAppBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateApp(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateAppMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateApp>>
|
|
>;
|
|
export type UpdateAppMutationBody = BodyType<UpdateAppBody>;
|
|
export type UpdateAppMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update app (admin)
|
|
*/
|
|
export const useUpdateApp = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateAppMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete app (admin)
|
|
*/
|
|
export const getDeleteAppUrl = (id: number) => {
|
|
return `/api/apps/${id}`;
|
|
};
|
|
|
|
export const deleteApp = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteAppUrl(id), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteAppMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteApp"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return deleteApp(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteAppMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteApp>>
|
|
>;
|
|
|
|
export type DeleteAppMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Delete app (admin)
|
|
*/
|
|
export const useDeleteApp = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteAppMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Log an app open event for the current user
|
|
*/
|
|
export const getLogAppOpenUrl = (id: number) => {
|
|
return `/api/apps/${id}/open`;
|
|
};
|
|
|
|
export const logAppOpen = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getLogAppOpenUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getLogAppOpenMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["logAppOpen"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return logAppOpen(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type LogAppOpenMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof logAppOpen>>
|
|
>;
|
|
|
|
export type LogAppOpenMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Log an app open event for the current user
|
|
*/
|
|
export const useLogAppOpen = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getLogAppOpenMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Set the current user's preferred home apps order
|
|
*/
|
|
export const getUpdateMyAppOrderUrl = () => {
|
|
return `/api/me/app-order`;
|
|
};
|
|
|
|
export const updateMyAppOrder = async (
|
|
updateMyAppOrderBody: UpdateMyAppOrderBody,
|
|
options?: RequestInit,
|
|
): Promise<App[]> => {
|
|
return customFetch<App[]>(getUpdateMyAppOrderUrl(), {
|
|
...options,
|
|
method: "PUT",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateMyAppOrderBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateMyAppOrderMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateMyAppOrder"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
{ data: BodyType<UpdateMyAppOrderBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateMyAppOrder(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateMyAppOrderMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>
|
|
>;
|
|
export type UpdateMyAppOrderMutationBody = BodyType<UpdateMyAppOrderBody>;
|
|
export type UpdateMyAppOrderMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Set the current user's preferred home apps order
|
|
*/
|
|
export const useUpdateMyAppOrder = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateMyAppOrderMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get application settings (public)
|
|
*/
|
|
export const getGetAppSettingsUrl = () => {
|
|
return `/api/settings`;
|
|
};
|
|
|
|
export const getAppSettings = async (
|
|
options?: RequestInit,
|
|
): Promise<AppSettings> => {
|
|
return customFetch<AppSettings>(getGetAppSettingsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetAppSettingsQueryKey = () => {
|
|
return [`/api/settings`] as const;
|
|
};
|
|
|
|
export const getGetAppSettingsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetAppSettingsQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getAppSettings>>> = ({
|
|
signal,
|
|
}) => getAppSettings({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAppSettingsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAppSettings>>
|
|
>;
|
|
export type GetAppSettingsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get application settings (public)
|
|
*/
|
|
|
|
export function useGetAppSettings<
|
|
TData = Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAppSettingsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update application settings (admin)
|
|
*/
|
|
export const getUpdateAppSettingsUrl = () => {
|
|
return `/api/settings`;
|
|
};
|
|
|
|
export const updateAppSettings = async (
|
|
updateAppSettingsBody: UpdateAppSettingsBody,
|
|
options?: RequestInit,
|
|
): Promise<AppSettings> => {
|
|
return customFetch<AppSettings>(getUpdateAppSettingsUrl(), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateAppSettingsBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateAppSettingsMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateAppSettings"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
{ data: BodyType<UpdateAppSettingsBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateAppSettings(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateAppSettingsMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateAppSettings>>
|
|
>;
|
|
export type UpdateAppSettingsMutationBody = BodyType<UpdateAppSettingsBody>;
|
|
export type UpdateAppSettingsMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Update application settings (admin)
|
|
*/
|
|
export const useUpdateAppSettings = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateAppSettingsMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Request a presigned URL for file upload
|
|
*/
|
|
export const getRequestUploadUrlUrl = () => {
|
|
return `/api/storage/uploads/request-url`;
|
|
};
|
|
|
|
export const requestUploadUrl = async (
|
|
requestUploadUrlBody: RequestUploadUrlBody,
|
|
options?: RequestInit,
|
|
): Promise<RequestUploadUrlResponse> => {
|
|
return customFetch<RequestUploadUrlResponse>(getRequestUploadUrlUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(requestUploadUrlBody),
|
|
});
|
|
};
|
|
|
|
export const getRequestUploadUrlMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["requestUploadUrl"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
{ data: BodyType<RequestUploadUrlBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return requestUploadUrl(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type RequestUploadUrlMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>
|
|
>;
|
|
export type RequestUploadUrlMutationBody = BodyType<RequestUploadUrlBody>;
|
|
export type RequestUploadUrlMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Request a presigned URL for file upload
|
|
*/
|
|
export const useRequestUploadUrl = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getRequestUploadUrlMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List all services
|
|
*/
|
|
export const getListServicesUrl = () => {
|
|
return `/api/services`;
|
|
};
|
|
|
|
export const listServices = async (
|
|
options?: RequestInit,
|
|
): Promise<Service[]> => {
|
|
return customFetch<Service[]>(getListServicesUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListServicesQueryKey = () => {
|
|
return [`/api/services`] as const;
|
|
};
|
|
|
|
export const getListServicesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listServices>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServices>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListServicesQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listServices>>> = ({
|
|
signal,
|
|
}) => listServices({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServices>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListServicesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listServices>>
|
|
>;
|
|
export type ListServicesQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List all services
|
|
*/
|
|
|
|
export function useListServices<
|
|
TData = Awaited<ReturnType<typeof listServices>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServices>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListServicesQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a service (admin)
|
|
*/
|
|
export const getCreateServiceUrl = () => {
|
|
return `/api/services`;
|
|
};
|
|
|
|
export const createService = async (
|
|
createServiceBody: CreateServiceBody,
|
|
options?: RequestInit,
|
|
): Promise<Service> => {
|
|
return customFetch<Service>(getCreateServiceUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createServiceBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateServiceMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createService"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
{ data: BodyType<CreateServiceBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createService(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateServiceMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createService>>
|
|
>;
|
|
export type CreateServiceMutationBody = BodyType<CreateServiceBody>;
|
|
export type CreateServiceMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Create a service (admin)
|
|
*/
|
|
export const useCreateService = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateServiceMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get service by ID
|
|
*/
|
|
export const getGetServiceUrl = (id: number) => {
|
|
return `/api/services/${id}`;
|
|
};
|
|
|
|
export const getService = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<Service> => {
|
|
return customFetch<Service>(getGetServiceUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetServiceQueryKey = (id: number) => {
|
|
return [`/api/services/${id}`] as const;
|
|
};
|
|
|
|
export const getGetServiceQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getService>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getService>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetServiceQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getService>>> = ({
|
|
signal,
|
|
}) => getService(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getService>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetServiceQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getService>>
|
|
>;
|
|
export type GetServiceQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get service by ID
|
|
*/
|
|
|
|
export function useGetService<
|
|
TData = Awaited<ReturnType<typeof getService>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getService>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetServiceQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update service (admin)
|
|
*/
|
|
export const getUpdateServiceUrl = (id: number) => {
|
|
return `/api/services/${id}`;
|
|
};
|
|
|
|
export const updateService = async (
|
|
id: number,
|
|
updateServiceBody: UpdateServiceBody,
|
|
options?: RequestInit,
|
|
): Promise<Service> => {
|
|
return customFetch<Service>(getUpdateServiceUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateServiceBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateServiceMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateService"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
{ id: number; data: BodyType<UpdateServiceBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateService(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateServiceMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateService>>
|
|
>;
|
|
export type UpdateServiceMutationBody = BodyType<UpdateServiceBody>;
|
|
export type UpdateServiceMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update service (admin)
|
|
*/
|
|
export const useUpdateService = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateServiceMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete service (admin)
|
|
*/
|
|
export const getDeleteServiceUrl = (id: number) => {
|
|
return `/api/services/${id}`;
|
|
};
|
|
|
|
export const deleteService = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteServiceUrl(id), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteServiceMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteService"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return deleteService(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteServiceMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteService>>
|
|
>;
|
|
|
|
export type DeleteServiceMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Delete service (admin)
|
|
*/
|
|
export const useDeleteService = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteServiceMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List service categories
|
|
*/
|
|
export const getListServiceCategoriesUrl = () => {
|
|
return `/api/service-categories`;
|
|
};
|
|
|
|
export const listServiceCategories = async (
|
|
options?: RequestInit,
|
|
): Promise<ServiceCategory[]> => {
|
|
return customFetch<ServiceCategory[]>(getListServiceCategoriesUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListServiceCategoriesQueryKey = () => {
|
|
return [`/api/service-categories`] as const;
|
|
};
|
|
|
|
export const getListServiceCategoriesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListServiceCategoriesQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listServiceCategories>>
|
|
> = ({ signal }) => listServiceCategories({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListServiceCategoriesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listServiceCategories>>
|
|
>;
|
|
export type ListServiceCategoriesQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List service categories
|
|
*/
|
|
|
|
export function useListServiceCategories<
|
|
TData = Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListServiceCategoriesQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List conversations for current user
|
|
*/
|
|
export const getListConversationsUrl = () => {
|
|
return `/api/conversations`;
|
|
};
|
|
|
|
export const listConversations = async (
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails[]> => {
|
|
return customFetch<ConversationWithDetails[]>(getListConversationsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListConversationsQueryKey = () => {
|
|
return [`/api/conversations`] as const;
|
|
};
|
|
|
|
export const getListConversationsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listConversations>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listConversations>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListConversationsQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listConversations>>
|
|
> = ({ signal }) => listConversations({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listConversations>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListConversationsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listConversations>>
|
|
>;
|
|
export type ListConversationsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List conversations for current user
|
|
*/
|
|
|
|
export function useListConversations<
|
|
TData = Awaited<ReturnType<typeof listConversations>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listConversations>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListConversationsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a conversation
|
|
*/
|
|
export const getCreateConversationUrl = () => {
|
|
return `/api/conversations`;
|
|
};
|
|
|
|
export const createConversation = async (
|
|
createConversationBody: CreateConversationBody,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(getCreateConversationUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createConversationBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateConversationMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createConversation"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
{ data: BodyType<CreateConversationBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createConversation(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateConversationMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createConversation>>
|
|
>;
|
|
export type CreateConversationMutationBody = BodyType<CreateConversationBody>;
|
|
export type CreateConversationMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Create a conversation
|
|
*/
|
|
export const useCreateConversation = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateConversationMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get conversation by ID
|
|
*/
|
|
export const getGetConversationUrl = (id: number) => {
|
|
return `/api/conversations/${id}`;
|
|
};
|
|
|
|
export const getConversation = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(getGetConversationUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetConversationQueryKey = (id: number) => {
|
|
return [`/api/conversations/${id}`] as const;
|
|
};
|
|
|
|
export const getGetConversationQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getConversation>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getConversation>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetConversationQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getConversation>>> = ({
|
|
signal,
|
|
}) => getConversation(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getConversation>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetConversationQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getConversation>>
|
|
>;
|
|
export type GetConversationQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get conversation by ID
|
|
*/
|
|
|
|
export function useGetConversation<
|
|
TData = Awaited<ReturnType<typeof getConversation>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getConversation>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetConversationQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List messages in a conversation
|
|
*/
|
|
export const getListMessagesUrl = (id: number) => {
|
|
return `/api/conversations/${id}/messages`;
|
|
};
|
|
|
|
export const listMessages = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<MessageWithSender[]> => {
|
|
return customFetch<MessageWithSender[]>(getListMessagesUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListMessagesQueryKey = (id: number) => {
|
|
return [`/api/conversations/${id}/messages`] as const;
|
|
};
|
|
|
|
export const getListMessagesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listMessages>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMessages>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListMessagesQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listMessages>>> = ({
|
|
signal,
|
|
}) => listMessages(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMessages>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListMessagesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listMessages>>
|
|
>;
|
|
export type ListMessagesQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List messages in a conversation
|
|
*/
|
|
|
|
export function useListMessages<
|
|
TData = Awaited<ReturnType<typeof listMessages>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMessages>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListMessagesQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Send a message
|
|
*/
|
|
export const getSendMessageUrl = (id: number) => {
|
|
return `/api/conversations/${id}/messages`;
|
|
};
|
|
|
|
export const sendMessage = async (
|
|
id: number,
|
|
sendMessageBody: SendMessageBody,
|
|
options?: RequestInit,
|
|
): Promise<MessageWithSender> => {
|
|
return customFetch<MessageWithSender>(getSendMessageUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(sendMessageBody),
|
|
});
|
|
};
|
|
|
|
export const getSendMessageMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["sendMessage"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
{ id: number; data: BodyType<SendMessageBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return sendMessage(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type SendMessageMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof sendMessage>>
|
|
>;
|
|
export type SendMessageMutationBody = BodyType<SendMessageBody>;
|
|
export type SendMessageMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Send a message
|
|
*/
|
|
export const useSendMessage = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getSendMessageMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Mark all messages in conversation as read
|
|
*/
|
|
export const getMarkConversationReadUrl = (id: number) => {
|
|
return `/api/conversations/${id}/read`;
|
|
};
|
|
|
|
export const markConversationRead = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getMarkConversationReadUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getMarkConversationReadMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["markConversationRead"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return markConversationRead(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type MarkConversationReadMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof markConversationRead>>
|
|
>;
|
|
|
|
export type MarkConversationReadMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Mark all messages in conversation as read
|
|
*/
|
|
export const useMarkConversationRead = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getMarkConversationReadMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List notifications for current user
|
|
*/
|
|
export const getListNotificationsUrl = () => {
|
|
return `/api/notifications`;
|
|
};
|
|
|
|
export const listNotifications = async (
|
|
options?: RequestInit,
|
|
): Promise<Notification[]> => {
|
|
return customFetch<Notification[]>(getListNotificationsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListNotificationsQueryKey = () => {
|
|
return [`/api/notifications`] as const;
|
|
};
|
|
|
|
export const getListNotificationsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listNotifications>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listNotifications>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListNotificationsQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listNotifications>>
|
|
> = ({ signal }) => listNotifications({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listNotifications>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListNotificationsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listNotifications>>
|
|
>;
|
|
export type ListNotificationsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List notifications for current user
|
|
*/
|
|
|
|
export function useListNotifications<
|
|
TData = Awaited<ReturnType<typeof listNotifications>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listNotifications>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListNotificationsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Mark notification as read
|
|
*/
|
|
export const getMarkNotificationReadUrl = (id: number) => {
|
|
return `/api/notifications/${id}/read`;
|
|
};
|
|
|
|
export const markNotificationRead = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<Notification> => {
|
|
return customFetch<Notification>(getMarkNotificationReadUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
});
|
|
};
|
|
|
|
export const getMarkNotificationReadMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["markNotificationRead"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return markNotificationRead(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type MarkNotificationReadMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof markNotificationRead>>
|
|
>;
|
|
|
|
export type MarkNotificationReadMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Mark notification as read
|
|
*/
|
|
export const useMarkNotificationRead = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getMarkNotificationReadMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Mark all notifications as read
|
|
*/
|
|
export const getMarkAllNotificationsReadUrl = () => {
|
|
return `/api/notifications/read-all`;
|
|
};
|
|
|
|
export const markAllNotificationsRead = async (
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getMarkAllNotificationsReadUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getMarkAllNotificationsReadMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["markAllNotificationsRead"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
void
|
|
> = () => {
|
|
return markAllNotificationsRead(requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type MarkAllNotificationsReadMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>
|
|
>;
|
|
|
|
export type MarkAllNotificationsReadMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Mark all notifications as read
|
|
*/
|
|
export const useMarkAllNotificationsRead = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
return useMutation(getMarkAllNotificationsReadMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List all users (admin)
|
|
*/
|
|
export const getListUsersUrl = () => {
|
|
return `/api/users`;
|
|
};
|
|
|
|
export const listUsers = async (
|
|
options?: RequestInit,
|
|
): Promise<UserProfile[]> => {
|
|
return customFetch<UserProfile[]>(getListUsersUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListUsersQueryKey = () => {
|
|
return [`/api/users`] as const;
|
|
};
|
|
|
|
export const getListUsersQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listUsers>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listUsers>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListUsersQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listUsers>>> = ({
|
|
signal,
|
|
}) => listUsers({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listUsers>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListUsersQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listUsers>>
|
|
>;
|
|
export type ListUsersQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List all users (admin)
|
|
*/
|
|
|
|
export function useListUsers<
|
|
TData = Awaited<ReturnType<typeof listUsers>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listUsers>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListUsersQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a user (admin)
|
|
*/
|
|
export const getCreateUserUrl = () => {
|
|
return `/api/users`;
|
|
};
|
|
|
|
export const createUser = async (
|
|
registerBody: RegisterBody,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getCreateUserUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(registerBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateUserMutationOptions = <
|
|
TError = ErrorType<void>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createUser"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
{ data: BodyType<RegisterBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createUser(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateUserMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createUser>>
|
|
>;
|
|
export type CreateUserMutationBody = BodyType<RegisterBody>;
|
|
export type CreateUserMutationError = ErrorType<void>;
|
|
|
|
/**
|
|
* @summary Create a user (admin)
|
|
*/
|
|
export const useCreateUser = <
|
|
TError = ErrorType<void>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateUserMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get user by ID (admin)
|
|
*/
|
|
export const getGetUserUrl = (id: number) => {
|
|
return `/api/users/${id}`;
|
|
};
|
|
|
|
export const getUser = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getGetUserUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetUserQueryKey = (id: number) => {
|
|
return [`/api/users/${id}`] as const;
|
|
};
|
|
|
|
export const getGetUserQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getUser>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getUser>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetUserQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getUser>>> = ({
|
|
signal,
|
|
}) => getUser(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<Awaited<ReturnType<typeof getUser>>, TError, TData> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
};
|
|
|
|
export type GetUserQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getUser>>
|
|
>;
|
|
export type GetUserQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get user by ID (admin)
|
|
*/
|
|
|
|
export function useGetUser<
|
|
TData = Awaited<ReturnType<typeof getUser>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getUser>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetUserQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update user (admin)
|
|
*/
|
|
export const getUpdateUserUrl = (id: number) => {
|
|
return `/api/users/${id}`;
|
|
};
|
|
|
|
export const updateUser = async (
|
|
id: number,
|
|
updateUserBody: UpdateUserBody,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getUpdateUserUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateUserBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateUserMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateUser"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
{ id: number; data: BodyType<UpdateUserBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateUser(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateUserMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateUser>>
|
|
>;
|
|
export type UpdateUserMutationBody = BodyType<UpdateUserBody>;
|
|
export type UpdateUserMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update user (admin)
|
|
*/
|
|
export const useUpdateUser = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateUserMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete user (admin)
|
|
*/
|
|
export const getDeleteUserUrl = (id: number) => {
|
|
return `/api/users/${id}`;
|
|
};
|
|
|
|
export const deleteUser = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteUserUrl(id), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteUserMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteUser"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return deleteUser(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteUserMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteUser>>
|
|
>;
|
|
|
|
export type DeleteUserMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Delete user (admin)
|
|
*/
|
|
export const useDeleteUser = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteUserMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get home screen stats
|
|
*/
|
|
export const getGetHomeStatsUrl = () => {
|
|
return `/api/stats/home`;
|
|
};
|
|
|
|
export const getHomeStats = async (
|
|
options?: RequestInit,
|
|
): Promise<HomeStats> => {
|
|
return customFetch<HomeStats>(getGetHomeStatsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetHomeStatsQueryKey = () => {
|
|
return [`/api/stats/home`] as const;
|
|
};
|
|
|
|
export const getGetHomeStatsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetHomeStatsQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getHomeStats>>> = ({
|
|
signal,
|
|
}) => getHomeStats({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetHomeStatsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getHomeStats>>
|
|
>;
|
|
export type GetHomeStatsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get home screen stats
|
|
*/
|
|
|
|
export function useGetHomeStats<
|
|
TData = Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetHomeStatsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Get admin dashboard trend stats
|
|
*/
|
|
export const getGetAdminStatsUrl = (params?: GetAdminStatsParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/stats/admin?${stringifiedParams}`
|
|
: `/api/stats/admin`;
|
|
};
|
|
|
|
export const getAdminStats = async (
|
|
params?: GetAdminStatsParams,
|
|
options?: RequestInit,
|
|
): Promise<AdminStats> => {
|
|
return customFetch<AdminStats>(getGetAdminStatsUrl(params), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetAdminStatsQueryKey = (params?: GetAdminStatsParams) => {
|
|
return [`/api/stats/admin`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getGetAdminStatsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
params?: GetAdminStatsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetAdminStatsQueryKey(params);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getAdminStats>>> = ({
|
|
signal,
|
|
}) => getAdminStats(params, { signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminStatsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminStats>>
|
|
>;
|
|
export type GetAdminStatsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get admin dashboard trend stats
|
|
*/
|
|
|
|
export function useGetAdminStats<
|
|
TData = Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
params?: GetAdminStatsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminStatsQueryOptions(params, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|