157 lines
3.9 KiB
TypeScript

import payloadConfig from "@/payload.config";
import { BlogData } from "@/schema/blog";
import { FetchBlogParams } from "@/schema/services/blog";
import { formatDate } from "@/utils/datetime";
import { getRandomNumber } from "@/utils/general";
import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
import { getPayload, Where } from "payload";
export async function fetchBlog({ page, search = "", categoryId, tagId }: FetchBlogParams = {}) {
const payload = await getPayload({ config: payloadConfig });
const queryCondition: Where = {
_status: { equals: "published" },
};
if (!!search) {
queryCondition["title"] = {
contains: search,
};
}
if (!!categoryId) {
queryCondition["categories"] = {
equals: categoryId,
};
}
if (!!tagId) {
queryCondition["tags"] = {
equals: tagId,
};
}
const blogDataQuery = await payload.find({
collection: "blogs",
page,
pagination: true,
limit: 9,
where: queryCondition,
});
const formattedData: BlogData[] = blogDataQuery.docs.map((item) => {
return {
slug: item.slug,
title: item.title,
description: sanitizeBlogContentIntoStringPreview(item.content),
img: typeof item.img !== "number" ? { url: item?.img?.url ?? "", alt: item.img.alt } : undefined,
posted_at: formatDate(item.createdAt),
};
});
return {
...blogDataQuery,
formattedData,
};
}
export async function fetchBlogSuggestion() {
const payload = await getPayload({ config: payloadConfig });
const limitPerPage = 2;
const blogCountQuery = await payload.count({
collection: "blogs",
where: { _status: { equals: "published" } },
});
// randomize page
let page = 1;
const totalDocs = blogCountQuery.totalDocs;
if (totalDocs > limitPerPage) {
const totalPage = Math.ceil(totalDocs / limitPerPage);
page = getRandomNumber(totalPage);
}
const blogDataQuery = await payload.find({
collection: "blogs",
page,
limit: limitPerPage,
});
const formattedData: BlogData[] = blogDataQuery.docs.map((item) => {
return {
slug: item.slug,
title: item.title,
description: sanitizeBlogContentIntoStringPreview(item.content),
img: typeof item.img !== "number" ? { url: item?.img?.url ?? "", alt: item.img.alt } : undefined,
posted_at: formatDate(item.createdAt),
};
});
return {
...blogDataQuery,
formattedData,
};
}
export async function fetchBlogDetail(slug: string | undefined) {
const payload = await getPayload({ config: payloadConfig });
const blogDataQuery = await payload.find({
collection: "blogs",
where: {
_status: { equals: "published" },
slug: { equals: slug },
},
limit: 1,
pagination: false,
});
if (!blogDataQuery?.docs?.[0]) return null;
const data = blogDataQuery?.docs?.[0];
const createdAt = formatDate(data.createdAt);
const updatedAt = formatDate(data.updatedAt);
const img = {
url: typeof data.img !== "number" ? (data?.img?.url ?? "") : "",
alt: typeof data.img !== "number" ? (data?.img?.alt ?? "") : "",
};
return {
data,
createdAt,
updatedAt,
img,
};
}
export async function fetchBlogCategoryBySlug(slug: string) {
const payload = await getPayload({ config: payloadConfig });
const category = await payload.find({
collection: "blogCategories",
where: {
_status: { equals: "published" },
slug: { equals: slug },
},
});
if (!category?.docs?.[0]) return null;
return {
data: category.docs[0],
};
}
export async function fetchBlogTagBySlug(slug: string) {
const payload = await getPayload({ config: payloadConfig });
const tag = await payload.find({
collection: "blogTags",
where: {
_status: { equals: "published" },
slug: { equals: slug },
},
});
if (!tag?.docs?.[0]) return null;
return {
data: tag.docs[0],
};
}