blog / src /client /hooks /usePosts.ts
hadadrjt's picture
blog: Bump to 0.0.1 version.
4524aaa
//
// SPDX-FileCopyrightText: Hadad <hadad@linuxmail.org>
// SPDX-License-Identifier: Apache-2.0
//
import { useState, useEffect, useCallback } from "react";
import type { Post, PostSummary, ApiResponse } from "@shared/types";
interface UsePostsResult {
posts: PostSummary[];
loading: boolean;
error: string | null;
refetch: () => Promise<void>;
}
interface UsePostResult {
post: Post | null;
loading: boolean;
error: string | null;
}
export const usePosts = (): UsePostsResult => {
const [posts, setPosts] = useState<PostSummary[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const fetchPosts = useCallback(async (): Promise<void> => {
setLoading(true);
setError(null);
try {
const response = await fetch("/api/posts");
const result: ApiResponse<PostSummary[]> = await response.json();
if (result.success && result.data) {
setPosts(result.data);
} else {
setError(result.error || "Failed to fetch posts");
}
} catch {
setError("Failed to connect to server");
} finally {
setLoading(false);
}
}, []);
useEffect((): void => {
fetchPosts();
}, [fetchPosts]);
return { posts, loading, error, refetch: fetchPosts };
};
export const usePost = (slug: string): UsePostResult => {
const [post, setPost] = useState<Post | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
useEffect((): void => {
const fetchPost = async (): Promise<void> => {
setLoading(true);
setError(null);
try {
const response = await fetch(`/api/posts/${slug}`);
const result: ApiResponse<Post> = await response.json();
if (result.success && result.data) {
setPost(result.data);
} else {
setError(result.error || "Post not found");
}
} catch {
setError("Failed to connect to server");
} finally {
setLoading(false);
}
};
fetchPost();
}, [slug]);
return { post, loading, error };
};