Skip to content

Commit

Permalink
✨ feat(apis): change how data is sourced for homepage
Browse files Browse the repository at this point in the history
  • Loading branch information
thathurtabit authored Aug 9, 2024
2 parents 6891bd5 + 33f66ed commit f6ce75c
Show file tree
Hide file tree
Showing 8 changed files with 331 additions and 133 deletions.
4 changes: 4 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const withPWA = nextPWA({
/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,
experimental: {
forceSwcTransforms: true,
swcPlugins: [["next-superjson-plugin", {}]],
},

/**
* If you are using `appDir` then you must comment the below `i18n` config out.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"next-auth": "^4.24.7",
"next-pwa": "^5.6.0",
"next-recaptcha-v3": "^1.4.1",
"next-superjson-plugin": "^0.6.3",
"react": "18.3.1",
"react-combine-reducers": "^1.1.1",
"react-dom": "18.3.1",
Expand Down
22 changes: 22 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

253 changes: 140 additions & 113 deletions public/sitemap-0.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/sw.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/hooks/post/read-latest-posts.hook.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { api } from "~/utils/api";

export type TUSeReadLatestPosts = ReturnType<typeof useReadLatestPosts>;

export const useReadLatestPosts = () => {
const { data, isFetching, error, isError } =
api.post.readLatestPosts.useQuery(undefined, {
Expand Down
171 changes: 152 additions & 19 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { PrismaClient } from "@prisma/client";
import type { GetStaticPropsResult } from "next";

import { SectionSubtitle } from "~/components/atoms/section-subtitle/section-subtitle";
import { CategoryRowsLinks } from "~/components/molecules/category-rows-links/category-rows-links";
import { Intro } from "~/components/molecules/intro/intro";
Expand All @@ -6,16 +9,16 @@ import { PageMainIndent } from "~/components/molecules/page-main-indent/page-mai
import { PostRowsLinks } from "~/components/molecules/post-rows-links/post-rows-links";
import { PostShort } from "~/components/molecules/post-short/post-short";
import { SharedHead } from "~/components/molecules/shared-head/shared-head";
import { useReadLatestPosts } from "~/hooks/post/read-latest-posts.hook";
import { useReadRandomCategoryPostCount } from "~/hooks/post/read-random-category-post-count";
import { useReadRandomPost } from "~/hooks/post/read-random-post.hook";
import { tagKeys } from "~/schemas/post/post.schema";
import { appDescription, appDomain, appStrapline } from "~/settings/constants";
import type { IHomePageProperties } from "~/types/page.types";
import { getShuffledArray } from "~/utils/get-shuffled-array";

export default function Home() {
const { latestPostsData, latestPostsDataIsFetching } = useReadLatestPosts();
const { randomPostData, randomPostDataIsFetching } = useReadRandomPost();
const { randomCategoryPostCountData, randomCategoryPostCountIsFetching } =
useReadRandomCategoryPostCount({});
export default function Home({
latestPostsData,
randomPostData,
randomCategoryPostCountData,
}: IHomePageProperties) {
return (
<>
<SharedHead
Expand All @@ -26,32 +29,162 @@ export default function Home() {
<PageMainIndent className="max-w-screen-2xl">
<section className="grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-10 lg:gap-24 w-full justify-center items-center">
<Intro />
<PostShort
isLoading={randomPostDataIsFetching}
postData={randomPostData}
className="md:max-w-md"
/>
<PostShort postData={randomPostData} className="md:max-w-md" />
<div className="flex flex-col items-start mb-10 md:mb-0 md:justify-self-end md:max-w-md w-full">
<SectionSubtitle className="mb-0">
Random categories
</SectionSubtitle>
<CategoryRowsLinks
isLoading={randomCategoryPostCountIsFetching}
categoryData={randomCategoryPostCountData}
itemsCount={10}
/>
</div>
<div className="md:max-w-md">
<SectionSubtitle className="mb-0">Latest posts</SectionSubtitle>
<PostRowsLinks
isLoading={latestPostsDataIsFetching}
postsData={latestPostsData}
itemsCount={10}
/>
<PostRowsLinks postsData={latestPostsData} itemsCount={10} />
</div>
</section>
</PageMainIndent>
</PageMain>
</>
);
}

// This function gets called at build time
export const getStaticProps = async (): Promise<
GetStaticPropsResult<IHomePageProperties>
> => {
const prisma = new PrismaClient();
const allPublishedPostsData = await prisma.post.findMany({
where: {
versions: {
some: {
published: true,
},
},
},
orderBy: {
createdAt: "desc",
},
select: {
author: {
select: {
id: true,
username: true,
image: true,
},
},
id: true,
title: true,
versions: {
select: {
author: true,
id: true,
title: true,
fileUnder: true,
acronym: true,
abbreviation: true,
slug: true,
tags: true,
updatedAt: true,
},
orderBy: {
updatedAt: "desc",
},
take: 1,
},
},
});

const latestPostsData: IHomePageProperties["latestPostsData"] =
allPublishedPostsData.slice(0, 10);

const allPostsWithAuthor = await prisma.post.findMany({
include: {
author: {
select: {
id: true,
username: true,
image: true,
},
},
versions: {
include: {
author: {
select: {
id: true,
username: true,
image: true,
},
},
},
take: 1,
orderBy: {
updatedAt: "desc",
},
where: {
published: true,
},
},
},
});

const categoryPosts = await prisma.post.findMany({
orderBy: {
createdAt: "desc",
},
select: {
versions: {
select: {
fileUnder: true,
published: true,
},
orderBy: {
updatedAt: "desc",
},
take: 1,
},
},
});

const initialEmptyCategoriesMap = new Map(
tagKeys.map((tagKey) => [tagKey, 0])
);

// eslint-disable-next-line unicorn/no-array-reduce -- Reduce might be the best way to do this
const postsInCategories = categoryPosts.reduce((accumulator, post) => {
const lastVersion = post.versions.at(-1);

if (!lastVersion) {
return accumulator;
}

const { fileUnder } = lastVersion;

const currentCount = accumulator.get(fileUnder);

if (currentCount === undefined) {
return accumulator;
}

accumulator.set(fileUnder, currentCount + 1);

return accumulator;
}, initialEmptyCategoriesMap);

const randomCategoryPostCountData = getShuffledArray([
...postsInCategories.entries(),
]).slice(0, 10);

const randomPostData: IHomePageProperties["randomPostData"] =
getShuffledArray(allPostsWithAuthor).at(0);

return {
props: {
latestPostsData,
randomPostData,
randomCategoryPostCountData,
},
revalidate: 24 * 60 * 60, // 24 hours
};
};
9 changes: 9 additions & 0 deletions src/types/page.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {
TTRPCReadCategoryPosts, TTRPCReadLatestPosts, TTRPCReadRandomCategoryPostCount, TTRPCReadRandomPost,
} from "./prisma.types";

export interface IHomePageProperties {
latestPostsData: TTRPCReadLatestPosts | TTRPCReadCategoryPosts;
randomPostData: TTRPCReadRandomPost;
randomCategoryPostCountData: NonNullable<TTRPCReadRandomCategoryPostCount>
}

0 comments on commit f6ce75c

Please sign in to comment.