dev #18

Merged
RizqiSyahrendra merged 2 commits from dev into main 2025-03-14 08:42:09 +00:00
5 changed files with 59 additions and 10 deletions

View File

@ -4,7 +4,7 @@ import { RichText } from "@payloadcms/richtext-lexical/react";
import { headers } from "next/headers"; import { headers } from "next/headers";
import Image from "next/image"; import Image from "next/image";
import { notFound } from "next/navigation"; import { notFound } from "next/navigation";
import Blog from "./Blog"; import BlogsSuggestion from "./BlogsSuggestion";
export interface BlogDetailProps { export interface BlogDetailProps {
slug: string | undefined; slug: string | undefined;
@ -121,7 +121,7 @@ export default async function BlogDetail({ slug }: BlogDetailProps) {
</section> </section>
{/* End Section */} {/* End Section */}
<div className="mb-5"> <div className="mb-5">
<Blog /> <BlogsSuggestion />
</div> </div>
</> </>
); );

View File

@ -1,13 +1,14 @@
import React from "react"; import React from "react";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { fetchBlog } from "@/services/payload/blog"; import { fetchBlogSuggestion } from "@/services/payload/blog";
import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize"; import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
export default async function Blog() { export default async function BlogsSuggestion() {
const data = await fetchBlog(); const data = await fetchBlogSuggestion();
if (!data?.totalDocs) return <></>; if (!data?.totalDocs) return <></>;
return ( return (
<> <>
{/* End Background Shape */} {/* End Background Shape */}
@ -25,13 +26,13 @@ export default async function Blog() {
{/* Blog Posts Grid */} {/* Blog Posts Grid */}
<div className="row mt-n30"> <div className="row mt-n30">
{/* Post Item */} {/* Post Item */}
{data?.formattedData?.slice(0, 2).map((elm: any, i: number) => ( {data?.formattedData?.map((elm, i) => (
<div key={i} className="post-prev-3 col-12 col-lg-10 offset-lg-1 col-xl-6 offset-xl-0 mt-30"> <div key={i} className="post-prev-3 col-12 col-lg-10 offset-lg-1 col-xl-6 offset-xl-0 mt-30">
<div className="post-prev-3-container d-block d-sm-flex"> <div className="post-prev-3-container d-block d-sm-flex">
<div className="post-prev-3-img"> <div className="post-prev-3-img">
<Link href={elm.slug}> <Link href={`/${elm.slug ?? ""}`}>
<Image <Image
src={elm.imgFormatted.url} src={elm?.imgFormatted?.url ?? ""}
width={400} width={400}
height={200} height={200}
alt="Add Image Description" alt="Add Image Description"
@ -41,7 +42,7 @@ export default async function Blog() {
</div> </div>
<div className="post-prev-3-intro"> <div className="post-prev-3-intro">
<h4 className="post-prev-3-title"> <h4 className="post-prev-3-title">
<Link href={elm.slug}>{elm.title}</Link> <Link href={`/${elm.slug ?? ""}`}>{elm.title}</Link>
</h4> </h4>
<div className="post-prev-3-text">{sanitizeBlogContentIntoStringPreview(elm.content)}</div> <div className="post-prev-3-text">{sanitizeBlogContentIntoStringPreview(elm.content)}</div>
<div className="post-prev-3-info clearfix"> <div className="post-prev-3-info clearfix">

View File

@ -1,5 +1,6 @@
import payloadConfig from "@/payload.config"; import payloadConfig from "@/payload.config";
import { formatDate } from "@/utils/datetime"; import { formatDate } from "@/utils/datetime";
import { getRandomNumber } from "@/utils/general";
import { getPayload, Where } from "payload"; import { getPayload, Where } from "payload";
type FetchBlogParams = { type FetchBlogParams = {
@ -12,7 +13,10 @@ type FetchBlogParams = {
export async function fetchBlog({ page, search = "", categoryId, tagId }: FetchBlogParams = {}) { export async function fetchBlog({ page, search = "", categoryId, tagId }: FetchBlogParams = {}) {
const payload = await getPayload({ config: payloadConfig }); const payload = await getPayload({ config: payloadConfig });
const queryCondition: Where = {}; const queryCondition: Where = {
_status: { equals: "published" },
};
if (!!search) { if (!!search) {
queryCondition["title"] = { queryCondition["title"] = {
contains: search, contains: search,
@ -51,11 +55,48 @@ export async function fetchBlog({ page, search = "", categoryId, tagId }: FetchB
}; };
} }
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 = blogDataQuery.docs.map((item) => {
return {
...item,
imgFormatted: typeof item.img !== "number" ? { url: item?.img?.url ?? "", alt: item.img.alt } : undefined,
createdAtFormatted: formatDate(item.createdAt),
};
});
return {
...blogDataQuery,
formattedData,
};
}
export async function fetchBlogDetail(slug: string | undefined) { export async function fetchBlogDetail(slug: string | undefined) {
const payload = await getPayload({ config: payloadConfig }); const payload = await getPayload({ config: payloadConfig });
const blogDataQuery = await payload.find({ const blogDataQuery = await payload.find({
collection: "blogs", collection: "blogs",
where: { where: {
_status: { equals: "published" },
slug: { equals: slug }, slug: { equals: slug },
}, },
limit: 1, limit: 1,
@ -82,6 +123,7 @@ export async function fetchBlogCategoryBySlug(slug: string) {
const category = await payload.find({ const category = await payload.find({
collection: "blogCategories", collection: "blogCategories",
where: { where: {
_status: { equals: "published" },
slug: { equals: slug }, slug: { equals: slug },
}, },
}); });
@ -98,6 +140,7 @@ export async function fetchBlogTagBySlug(slug: string) {
const tag = await payload.find({ const tag = await payload.find({
collection: "blogTags", collection: "blogTags",
where: { where: {
_status: { equals: "published" },
slug: { equals: slug }, slug: { equals: slug },
}, },
}); });

View File

@ -11,6 +11,7 @@ export const fetchPageBySlug = async ({ slug }: { slug: string | undefined }) =>
pagination: false, pagination: false,
// overrideAccess: draft, // overrideAccess: draft,
where: { where: {
_status: { equals: "published" },
slug: { slug: {
equals: slug, equals: slug,
}, },

View File

@ -1,3 +1,7 @@
export function limitString(text: string) { export function limitString(text: string) {
return `${text.length > 100 ? `${text.slice(0, 100)}...` : text}`; return `${text.length > 100 ? `${text.slice(0, 100)}...` : text}`;
} }
export function getRandomNumber(range: number): number {
return Math.floor(Math.random() * range) + 1;
}