replaced per-endpoint helpers with ts-rest contract and typed client

This commit is contained in:
2026-01-28 13:01:28 +00:00
parent aa24de2e8e
commit d6af2032db
71 changed files with 1042 additions and 1075 deletions

View File

@@ -1,12 +1,19 @@
import type { UserRecord, UserUpdateRequest } from "@sprint/shared";
import type { UserResponse, UserUpdateRequest } from "@sprint/shared";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { queryKeys } from "@/lib/query/keys";
import { user } from "@/lib/server";
import { apiClient } from "@/lib/server";
export function useUserByUsername(username?: string | null) {
return useQuery<UserRecord>({
return useQuery<UserResponse>({
queryKey: queryKeys.users.byUsername(username ?? ""),
queryFn: () => user.byUsername(username ?? ""),
queryFn: async () => {
const { data, error } = await apiClient.userByUsername({
query: { username: username ?? "" },
});
if (error) throw new Error(error);
if (!data) throw new Error("user not found");
return data as UserResponse;
},
enabled: Boolean(username),
});
}
@@ -14,9 +21,14 @@ export function useUserByUsername(username?: string | null) {
export function useUpdateUser() {
const queryClient = useQueryClient();
return useMutation<UserRecord, Error, UserUpdateRequest>({
return useMutation<UserResponse, Error, UserUpdateRequest>({
mutationKey: ["users", "update"],
mutationFn: user.update,
mutationFn: async (input) => {
const { data, error } = await apiClient.userUpdate({ body: input });
if (error) throw new Error(error);
if (!data) throw new Error("failed to update user");
return data as UserResponse;
},
onSuccess: (_data) => {
queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
},
@@ -28,7 +40,14 @@ export function useUploadAvatar() {
return useMutation<string, Error, File>({
mutationKey: ["users", "upload-avatar"],
mutationFn: user.uploadAvatar,
mutationFn: async (file) => {
const formData = new FormData();
formData.append("file", file);
const { data, error } = await apiClient.userUploadAvatar({ body: formData });
if (error) throw new Error(error);
if (!data) throw new Error("failed to upload avatar");
return (data as { avatarURL: string }).avatarURL;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
},