import {
QueryClient,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
function usePosts(params: ListPostsParams) {
return useQuery({
queryKey: createPostsCacheKey(params),
queryFn: async () => {
const search = new URLSearchParams({
page: String(params.page ?? 1),
limit: String(params.limit ?? 10),
sort: params.sort ?? "desc",
});
for (const status of params.status ?? []) search.append("status", status);
for (const type of params.contentType ?? []) {
search.append("contentType", type);
}
const response = await fetch(
`https://api.usenotra.com/v1/posts?${search.toString()}`,
{
headers: {
Authorization: `Bearer ${process.env.NOTRA_API_KEY}`,
},
}
);
if (!response.ok) throw new Error("Failed to fetch posts");
return response.json();
},
});
}
function useUpdatePost() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({
postId,
updates,
}: {
postId: string;
updates: { title?: string; markdown?: string; status?: "draft" | "published" };
}) => {
const response = await fetch(`https://api.usenotra.com/v1/posts/${postId}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.NOTRA_API_KEY}`,
},
body: JSON.stringify(updates),
});
if (!response.ok) throw new Error("Failed to update post");
return response.json();
},
onSuccess: (_data, { postId }) => {
queryClient.invalidateQueries({ queryKey: ["notra", "posts"] });
queryClient.invalidateQueries({ queryKey: ["notra", "post", postId] });
},
});
}