dev #3
@ -10,8 +10,10 @@ export const metadata = {
|
|||||||
description: "Blog - Cochise Oncology",
|
description: "Blog - Cochise Oncology",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function BlogPage({ searchParams }: { searchParams?: Promise<{ page?: string }> }) {
|
export default async function BlogPage({ searchParams }: { searchParams?: Promise<{ page?: string; s?: string }> }) {
|
||||||
const paramsPage = (await searchParams)?.page;
|
const params = await searchParams;
|
||||||
|
const paramsPage = params?.page;
|
||||||
|
const paramsSearch = params?.s;
|
||||||
const page = sanitizePageNumber(paramsPage);
|
const page = sanitizePageNumber(paramsPage);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -32,9 +34,28 @@ export default async function BlogPage({ searchParams }: { searchParams?: Promis
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<div className="px-3 md:px-4 mt-4 lg:w-2/3 lg:mx-auto">
|
||||||
|
<form action="/blog" method="GET">
|
||||||
|
<div className="input-group">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="s"
|
||||||
|
defaultValue={paramsSearch ?? ""}
|
||||||
|
placeholder="Search blog..."
|
||||||
|
className="input-lg input-circle form-control"
|
||||||
|
/>
|
||||||
|
<div className="input-group-append">
|
||||||
|
<button className="btn btn-info text-white" type="submit">
|
||||||
|
Search
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<section className="page-section" id="blog">
|
<section className="page-section" id="blog">
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<Blogs page={page} />
|
<Blogs page={page} search={paramsSearch} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
--ext-color-primary-3: #2e2d51;
|
--ext-color-primary-3: #2e2d51;
|
||||||
--ext-color-primary-4: #d4a187;
|
--ext-color-primary-4: #d4a187;
|
||||||
--ext-color-primary-5: #e7ccc0;
|
--ext-color-primary-5: #e7ccc0;
|
||||||
|
--ext-color-primary-6: #64b3b4;
|
||||||
--background: #ffffff;
|
--background: #ffffff;
|
||||||
--foreground: #171717;
|
--foreground: #171717;
|
||||||
}
|
}
|
||||||
@ -19,6 +20,7 @@
|
|||||||
--ext-color-primary-3: #2e2d51;
|
--ext-color-primary-3: #2e2d51;
|
||||||
--ext-color-primary-4: #d4a187;
|
--ext-color-primary-4: #d4a187;
|
||||||
--ext-color-primary-5: #e7ccc0;
|
--ext-color-primary-5: #e7ccc0;
|
||||||
|
--ext-color-primary-6: #64b3b4;
|
||||||
--background: #0a0a0a;
|
--background: #0a0a0a;
|
||||||
--foreground: #ededed;
|
--foreground: #ededed;
|
||||||
}
|
}
|
||||||
@ -34,18 +36,25 @@ body {
|
|||||||
.ext-btn {
|
.ext-btn {
|
||||||
@apply py-2 px-4 rounded-full hover:opacity-95 hover:scale-95 transition-transform font-semibold no-underline;
|
@apply py-2 px-4 rounded-full hover:opacity-95 hover:scale-95 transition-transform font-semibold no-underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ext-btn-primary {
|
.ext-btn-primary {
|
||||||
@apply bg-extColorPrimary text-white;
|
@apply bg-extColorPrimary text-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ext-btn-primary2 {
|
.ext-btn-primary2 {
|
||||||
@apply bg-extColorPrimary2 text-white;
|
@apply bg-extColorPrimary2 text-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ext-btn-primary3 {
|
.ext-btn-primary3 {
|
||||||
@apply bg-extColorPrimary3 text-white;
|
@apply bg-extColorPrimary3 text-white;
|
||||||
}
|
}
|
||||||
|
.ext-btn-primary4 {
|
||||||
|
@apply bg-extColorPrimary4 text-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ext-btn-shadow-sm {
|
||||||
|
@apply py-2 px-3 rounded-full text-sm font-medium no-underline shadow-[0px_0px_10px_0px_rgba(0,0,0,0.5)];
|
||||||
|
}
|
||||||
|
.ext-btn-shadow-sm-primary4 {
|
||||||
|
@apply bg-extColorPrimary4 text-white hover:text-white hover:bg-extColorPrimary6 transition-colors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-gradient {
|
.bg-gradient {
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
@use "../css/queries.scss" as *;
|
|
||||||
|
|
||||||
.form {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hasSubmitted {
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 80vh;
|
|
||||||
|
|
||||||
@include small-break {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro {
|
|
||||||
margin-bottom: var(--base);
|
|
||||||
|
|
||||||
@include mid-break {
|
|
||||||
margin-bottom: var(--base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.confirmationMessage {
|
|
||||||
max-width: 800px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fieldWrap {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-left: calc(var(--base) * -0.5);
|
|
||||||
margin-right: calc(var(--base) * -0.5);
|
|
||||||
width: calc(100% + #{var(--base)});
|
|
||||||
|
|
||||||
> * {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.Select {
|
|
||||||
& label {
|
|
||||||
position: absolute;
|
|
||||||
top: calc(var(--base) * -0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebarContent {
|
|
||||||
@include mid-break {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobileSidebar {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@include mid-break {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: calc(var(--base) * 2);
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,36 +19,21 @@ export interface BlogCardItemProps {
|
|||||||
|
|
||||||
export function BlogCardItem({ data }: BlogCardItemProps) {
|
export function BlogCardItem({ data }: BlogCardItemProps) {
|
||||||
return (
|
return (
|
||||||
<div className="post-prev-3 col-12 col-lg-10 offset-lg-1 col-xl-6 offset-xl-0 mt-50">
|
<div className="post-prev-3 col-12 col-md-6 col-lg-4 col-xl-4 mt-50">
|
||||||
<div className="post-prev-3-container d-block d-sm-flex">
|
<div className="post-prev-3-container flex flex-col">
|
||||||
<div className="post-prev-3-img">
|
<div>
|
||||||
<a href={`/${data.slug}/`}>
|
<a href={`/${data.slug}/`}>
|
||||||
<Image width={400} height={488} src={data?.img?.url ?? ""} alt={data?.img?.alt ?? ""} />
|
<Image width={684} height={454} src={data?.img?.url ?? ""} alt={data?.img?.alt ?? ""} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="post-prev-3-intro">
|
<div className="px-4 py-3 h-full flex flex-col justify-between">
|
||||||
<h4 className="post-prev-3-title">
|
<h2 className="text-lg text-center">
|
||||||
<a href={`/${data.slug}/`}>{data.title}</a>
|
<a href={`/${data.slug}/`}>{data.title}</a>
|
||||||
</h4>
|
</h2>
|
||||||
<div className="post-prev-3-text">{data.contentPreview}</div>
|
<div className="flex justify-center mt-2">
|
||||||
<div className="post-prev-3-info clearfix">
|
<a href={`/${data.slug}/`} className="ext-btn-shadow-sm ext-btn-shadow-sm-primary4">
|
||||||
{!!data?.author?.name && (
|
Continue Reading
|
||||||
<div className="float-start">
|
|
||||||
<a href="#">
|
|
||||||
<Image
|
|
||||||
className="post-prev-3-author-img"
|
|
||||||
width={30}
|
|
||||||
height={30}
|
|
||||||
src={data.author?.img ?? "#"}
|
|
||||||
alt="Image Description"
|
|
||||||
/>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="#">{data.author.name}</a>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className={!!data?.author?.name ? "float-end" : "float-start"}>
|
|
||||||
<a href="#">{data.date}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -58,22 +43,14 @@ export function BlogCardItem({ data }: BlogCardItemProps) {
|
|||||||
|
|
||||||
export function BlogCardItemSkeleton() {
|
export function BlogCardItemSkeleton() {
|
||||||
return (
|
return (
|
||||||
<div className="post-prev-3 col-12 col-lg-10 offset-lg-1 col-xl-6 offset-xl-0 mt-50 animate-pulse">
|
<div className="post-prev-3 col-12 col-md-6 col-lg-4 col-xl-4 mt-50 animate-pulse">
|
||||||
<div className="post-prev-3-container d-block d-sm-flex">
|
<div className="post-prev-3-container flex flex-col">
|
||||||
<div className="post-prev-3-img">
|
<div className="h-48 w-full bg-gray-300"></div>
|
||||||
<div className="w-56 h-64 bg-gray-300 rounded-l-lg"></div>
|
<div className="px-4 py-3">
|
||||||
</div>
|
<div className="space-y-2 flex flex-col items-center">
|
||||||
<div className="post-prev-3-intro flex flex-1">
|
<div className="h-4 bg-gray-300 rounded w-full"></div>
|
||||||
<div className="flex flex-col flex-1 justify-between">
|
<div className="h-4 bg-gray-300 rounded w-full"></div>
|
||||||
<div>
|
<div className="h-4 bg-gray-300 rounded w-1/2"></div>
|
||||||
<div className="h-5 bg-gray-300 rounded w-3/4 mb-2"></div>
|
|
||||||
<div className="h-4 bg-gray-300 rounded w-5/6 mb-2"></div>
|
|
||||||
<div className="h-4 bg-gray-300 rounded w-2/3"></div>
|
|
||||||
<div className="h-3 bg-gray-300 rounded w-1/4 mt-3"></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="h-3 bg-gray-300 rounded w-1/4 mt-3"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,10 +5,11 @@ import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
|
|||||||
|
|
||||||
export interface BlogsProps {
|
export interface BlogsProps {
|
||||||
page: number;
|
page: number;
|
||||||
|
search?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function Blogs({ page }: BlogsProps) {
|
export default async function Blogs({ page, search }: BlogsProps) {
|
||||||
const data = await fetchBlog(page);
|
const data = await fetchBlog(page, search);
|
||||||
|
|
||||||
if (!data?.totalDocs) return <></>;
|
if (!data?.totalDocs) return <></>;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useRouter } from "next/navigation";
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
interface PaginationProps {
|
interface PaginationProps {
|
||||||
@ -13,13 +13,18 @@ interface PaginationProps {
|
|||||||
export default function Pagination({ page, hasPreviousPage, hasNextPage, totalPages }: PaginationProps) {
|
export default function Pagination({ page, hasPreviousPage, hasNextPage, totalPages }: PaginationProps) {
|
||||||
const activePage = page;
|
const activePage = page;
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const pathName = usePathname();
|
||||||
|
|
||||||
// Function to handle page change
|
// Function to handle page change
|
||||||
const handlePageChange = (page: string | number) => {
|
const handlePageChange = (page: string | number) => {
|
||||||
if (typeof page === "string") return;
|
if (typeof page === "string") return;
|
||||||
if (typeof window === "undefined") return;
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
router.push(`/blog/?page=${page}`);
|
const url = new URL(window.location.href);
|
||||||
|
const searchParams = new URLSearchParams(url.search);
|
||||||
|
searchParams.set("page", `${page}`);
|
||||||
|
|
||||||
|
router.push(`${pathName}/?${searchParams}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPageNumbers = () => {
|
const getPageNumbers = () => {
|
||||||
|
@ -2,17 +2,32 @@ import payloadConfig from "@/payload.config";
|
|||||||
import { formatDate } from "@/utils/datetime";
|
import { formatDate } from "@/utils/datetime";
|
||||||
import { getPayload } from "payload";
|
import { getPayload } from "payload";
|
||||||
|
|
||||||
export async function fetchBlog(page: number | undefined) {
|
export async function fetchBlog(page: number | undefined, search: string = "") {
|
||||||
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",
|
||||||
page,
|
page,
|
||||||
pagination: true,
|
pagination: true,
|
||||||
limit: 6,
|
limit: 6,
|
||||||
where: {
|
where: !search
|
||||||
|
? {
|
||||||
is_published: {
|
is_published: {
|
||||||
equals: true,
|
equals: true,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
and: [
|
||||||
|
{
|
||||||
|
is_published: {
|
||||||
|
equals: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
contains: search,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ export default {
|
|||||||
extColorPrimary2: "var(--ext-color-primary-2)",
|
extColorPrimary2: "var(--ext-color-primary-2)",
|
||||||
extColorPrimary3: "var(--ext-color-primary-3)",
|
extColorPrimary3: "var(--ext-color-primary-3)",
|
||||||
extColorPrimary4: "var(--ext-color-primary-4)",
|
extColorPrimary4: "var(--ext-color-primary-4)",
|
||||||
|
extColorPrimary5: "var(--ext-color-primary-5)",
|
||||||
|
extColorPrimary6: "var(--ext-color-primary-6)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user