Files
my-website-v2/frontend/routes/authors/[id].tsx

114 lines
3.1 KiB
TypeScript

import { FreshContext, Handlers, PageProps } from "$fresh/server.ts";
import AuthorCard from "../../components/AuthorCard.tsx";
import { Post } from "../../types/index.ts";
import { PostCarousel } from "../../components/PostCarousel.tsx";
import { PaginationControl } from "../../components/PaginationControl.tsx";
export const handler: Handlers<PageData> = {
async GET(req: Request, ctx: FreshContext) {
try {
const url = new URL(req.url);
const page = parseInt(url.searchParams.get("page") || "1");
const limit = parseInt(url.searchParams.get("limit") || "12");
const [authorResponse, authorPostResponse] = await Promise.all([
fetch(`${Deno.env.get("BASE_URI_API")}/authors/${ctx.params.id}`),
fetch(
`${Deno.env.get("BASE_URI_API")}/authors/${ctx.params.id}/posts?page=${page}&limit=${limit}`,
),
]);
const [authorData, authorPostData] = await Promise.all([
authorResponse.json(),
authorPostResponse.json(),
]);
let paginatedData: PaginatedPosts;
if (authorPostData.posts && authorPostData.total_posts !== undefined) {
const totalPages = Math.ceil(authorPostData.total_posts / limit);
paginatedData = {
posts: authorPostData.posts,
currentPage: page,
totalPages,
hasNextPage: page < totalPages,
hasPrevPage: page > 1,
totalPosts: authorPostData.total_posts,
};
} else {
const allPosts = Array.isArray(authorPostData) ? authorPostData : [];
const totalPages = Math.ceil(allPosts.length / limit);
const startIndex = (page - 1) * limit;
const endIndex = startIndex + limit;
paginatedData = {
posts: allPosts.slice(startIndex, endIndex),
currentPage: page,
totalPages,
hasNextPage: page < totalPages,
hasPrevPage: page > 1,
totalPosts: allPosts.length,
};
}
return ctx.render({
authorData,
authorPostData: paginatedData,
});
} catch (error) {
return ctx.render({
error: error.message,
authorData: null,
authorPostData: [],
});
}
},
};
export default function AuthorIdentifier({ data, url }: PageProps<PageData>) {
const { authorData, authorPostData, error } = data;
if (error) {
return (
<div>
<h1>Error Loading Author Information</h1>
<p>{error}</p>
</div>
);
}
if (!authorData) {
return <div>No author found</div>;
}
return (
<>
<div>
<AuthorCard author={authorData} isIdentified={true} />
</div>
<div>
<PostCarousel posts={authorPostData.posts} />
<PaginationControl
paginatedData={authorPostData}
currentUrl={url}
authorId={authorData.author_id}
/>
</div>
</>
);
}
interface PageData {
error?: string;
authorData: AuthorResponse;
authorPostData: Array<Post>;
}
export type AuthorResponse = {
author_id: number;
first_name: string;
last_name: string;
bio: string;
image?: string;
};