Commit 0d8da6c7 by Madhankumar

api changes for search

parent 1ab8e591
// api/search/index.js
import { getPosts } from "@lib/api";
import { NextResponse } from "next/server";
export async function GET(request) {
const { searchParams } = new URL(request.url);
const page = searchParams.get("page");
const search = searchParams.get("search");
const { blogs } = await getPosts("posts", 1);
const filterBlog = blogs.filter((e) => {
return e.title.toLowerCase().includes(search.toLowerCase());
});
let pageNo = filterBlog.length > 6 ? page : 1;
const itemsPerPage = 6;
// Calculate the start and end indices for the current page
const startIndex = (pageNo - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const slicedData = Array.isArray(filterBlog)
? filterBlog.slice(startIndex, endIndex)
: [];
const response = { data: slicedData, total: filterBlog.length };
return NextResponse.json(response);
}
import BlogLists from "@components/top-level/blog-lists"; import BlogLists from "@components/top-level/blog-lists";
import { getPosts } from "@lib/api"; import { getPosts, getPostsBySearch } from "@lib/api";
import styles from "./page.module.css"; import styles from "./page.module.css";
async function fetchBlogsByTitle(pageNo, search) {
try {
const searchResponse = await fetch(
`http://localhost:3000/api/blogs/?page=${pageNo}&search=${search}`
// {
// next: {
// revalidate: 100, //after 100sec
// },
// }
);
return await searchResponse.json();
} catch (err) {
console.log(er.message);
}
}
const Home = async ({ searchParams }) => { const Home = async ({ searchParams }) => {
let blogs = []; let blogs = [];
let blogsLength = 0; let pageNo = searchParams.page;
let pageNo = searchParams.page || 1; let search = searchParams.search;
let search = searchParams.search || "";
let response;
if (!search) {
try {
const { data, total } = await getPosts("posts", pageNo);
response = { data, total: total };
} catch (err) {
console.log(err.message);
}
} else {
response = await fetchBlogsByTitle(pageNo, search);
}
let response;
response = await getPosts("posts", pageNo);
blogs = response.data; blogs = response.data;
blogsLength = response.total;
pageNo = blogsLength > 6 ? pageNo : 1; // if length goes greater than 6 then take pagenum otherwise 1
if ("search" in searchParams && pageNo !== "") {
if (search !== "") {
console.log("dfknb", pageNo);
response = await getPostsBySearch("posts", pageNo, search);
blogs = response.data;
} else {
blogs.length = 0;
}
}
return ( return (
<div className={styles.container}> <div className={styles.container}>
{blogs?.length ? ( {blogs?.length ? (
...@@ -45,8 +27,9 @@ const Home = async ({ searchParams }) => { ...@@ -45,8 +27,9 @@ const Home = async ({ searchParams }) => {
title="Lifestyle" title="Lifestyle"
description="Lorem ipsum dolor sit amet elit. Id quaerat amet ipsum sunt et quos dolorum." description="Lorem ipsum dolor sit amet elit. Id quaerat amet ipsum sunt et quos dolorum."
blogs={blogs} blogs={blogs}
totalBlogLength={Number(blogsLength)} total={response.total}
currentPage={Number(pageNo)} currentPage={Number(pageNo)}
search={search}
/> />
) : ( ) : (
<h2 className="center">No data found</h2> <h2 className="center">No data found</h2>
......
...@@ -2,19 +2,8 @@ import SingleBlog from "@components/top-level/single-blog"; ...@@ -2,19 +2,8 @@ import SingleBlog from "@components/top-level/single-blog";
import Loading from "app/loading"; import Loading from "app/loading";
import { getPostById } from "@lib/api"; import { getPostById } from "@lib/api";
const fetchBlogById = async (id) => {
try {
const blogPost = await getPostById("posts", id);
return blogPost[0];
} catch (error) {
console.error("Error fetching blog:", error.message);
return null;
}
};
const SingleBlogApp = async ({ params: { id } }) => { const SingleBlogApp = async ({ params: { id } }) => {
const blog = await fetchBlogById(id); const blog = await getPostById("posts", id);
return <div>{blog ? <SingleBlog {...blog} /> : <Loading />}</div>; return <div>{blog ? <SingleBlog {...blog} /> : <Loading />}</div>;
}; };
......
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import Link from "next/link";
import cn from "classnames"; import cn from "classnames";
import styles from "./styles.module.css"; import styles from "./styles.module.css";
const Button = ({ children, isDisabled, variant, className, ...props }) => { const Button = ({
children,
disabled = false,
variant,
className,
href,
...props
}) => {
const classNames = cn(styles["btn"], { const classNames = cn(styles["btn"], {
[styles[variant]]: variant, [styles[variant]]: variant,
[styles[className]]: className, [styles[className]]: className,
[styles.disabled]: isDisabled, [styles.disabled]: disabled,
}); });
return ( return (
<button className={classNames} disabled={isDisabled} {...props}> <Link href={href} className={classNames} {...props}>
{children} {children}
</button> </Link>
); );
}; };
......
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
color: var(--secondary-color); color: var(--secondary-color);
} }
.disabled { .disabled {
opacity: 0.9; pointer-events: none;
color: #a3a3a3;
background-color: #e3e3e3;
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
......
"use client";
import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import Card from "@components/base/card"; import Card from "@components/base/card";
import Pagination from "@components/top-level/pagination"; import Pagination from "@components/top-level/pagination";
import { useRouter, useSearchParams } from "next/navigation";
import styles from "./styles.module.css"; import styles from "./styles.module.css";
const BlogLists = ({ const BlogLists = ({
...@@ -11,24 +8,9 @@ const BlogLists = ({ ...@@ -11,24 +8,9 @@ const BlogLists = ({
description, description,
blogs, blogs,
currentPage, currentPage,
totalBlogLength, total,
search,
}) => { }) => {
const router = useRouter();
const searchParams = useSearchParams();
const redirect = (pageNumber) => {
const searchQuery = searchParams.get("search")
? `&search=${searchParams.get("search")}`
: "";
const newUrl = `?page=${pageNumber}${searchQuery}`;
return router.push(newUrl, undefined, { shallow: true });
};
const handlePageChange = (pageNumber) => {
redirect(pageNumber);
// window.scrollTo({ top: 0, behavior: "smooth" });
};
return ( return (
<div className={styles["blog-container"]}> <div className={styles["blog-container"]}>
<h2 className={styles.title}>{title}</h2> <h2 className={styles.title}>{title}</h2>
...@@ -42,10 +24,10 @@ const BlogLists = ({ ...@@ -42,10 +24,10 @@ const BlogLists = ({
</div> </div>
<div className={styles.pagination}> <div className={styles.pagination}>
<Pagination <Pagination
currentPage={Number(currentPage)} currentPage={currentPage}
total={Number(totalBlogLength)} total={Number(total)}
perPage={6} perPage={6}
onPageChange={handlePageChange} search={search}
/> />
</div> </div>
</div> </div>
...@@ -57,7 +39,7 @@ BlogLists.propTypes = { ...@@ -57,7 +39,7 @@ BlogLists.propTypes = {
description: PropTypes.string, description: PropTypes.string,
blogs: PropTypes.array, blogs: PropTypes.array,
currentPage: PropTypes.number, currentPage: PropTypes.number,
totalBlogLength: PropTypes.number, total: PropTypes.number,
}; };
export default BlogLists; export default BlogLists;
...@@ -2,7 +2,7 @@ import PropTypes from "prop-types"; ...@@ -2,7 +2,7 @@ import PropTypes from "prop-types";
import Button from "@components/base/button"; import Button from "@components/base/button";
import styles from "./styles.module.css"; import styles from "./styles.module.css";
function Pagination({ total, currentPage, onPageChange, perPage }) { function Pagination({ total, currentPage, perPage, search }) {
const totalPages = Math.ceil(total / perPage); const totalPages = Math.ceil(total / perPage);
const totalPage = totalPages <= 1 ? 1 : totalPages; const totalPage = totalPages <= 1 ? 1 : totalPages;
...@@ -10,11 +10,6 @@ function Pagination({ total, currentPage, onPageChange, perPage }) { ...@@ -10,11 +10,6 @@ function Pagination({ total, currentPage, onPageChange, perPage }) {
for (let i = 1; i <= totalPage; i++) { for (let i = 1; i <= totalPage; i++) {
numberOfPages.push(i); numberOfPages.push(i);
} }
const handleCurrentPage = (item) => {
onPageChange(item);
};
// Logic for displaying buttons // Logic for displaying buttons
let tempNumberOfPages = []; let tempNumberOfPages = [];
let dotsLeft = "..."; let dotsLeft = "...";
...@@ -48,8 +43,12 @@ function Pagination({ total, currentPage, onPageChange, perPage }) { ...@@ -48,8 +43,12 @@ function Pagination({ total, currentPage, onPageChange, perPage }) {
<span className={styles.previous}> <span className={styles.previous}>
<Button <Button
variant="secondary" variant="secondary"
isDisabled={currentPage <= 1} disabled={currentPage <= 1}
onClick={() => handleCurrentPage(currentPage - 1)} href={
search
? `?page=${currentPage - 1}&search=${search}`
: `?page=${currentPage - 1}`
}
> >
&laquo; Prev &laquo; Prev
</Button> </Button>
...@@ -57,9 +56,15 @@ function Pagination({ total, currentPage, onPageChange, perPage }) { ...@@ -57,9 +56,15 @@ function Pagination({ total, currentPage, onPageChange, perPage }) {
{tempNumberOfPages.map((item, index) => ( {tempNumberOfPages.map((item, index) => (
<span key={index}> <span key={index}>
<Button <Button
isDisabled={totalPage === 1} disabled={totalPage === "1"}
variant={currentPage === item ? "primary" : "secondary"} variant={currentPage === item ? "primary" : "secondary"}
onClick={() => (item === "..." ? "" : handleCurrentPage(item))} href={
item === "..."
? ""
: search
? `?page=${item}&search=${search}`
: `?page=${item}`
}
> >
{item} {item}
</Button> </Button>
...@@ -68,8 +73,12 @@ function Pagination({ total, currentPage, onPageChange, perPage }) { ...@@ -68,8 +73,12 @@ function Pagination({ total, currentPage, onPageChange, perPage }) {
<span className={styles.next}> <span className={styles.next}>
<Button <Button
variant="secondary" variant="secondary"
isDisabled={currentPage === totalPage} disabled={currentPage === totalPage}
onClick={() => handleCurrentPage(currentPage + 1)} href={
search
? `?page=${currentPage + 1}&search=${search}`
: `?page=${currentPage + 1}`
}
> >
Next &raquo; Next &raquo;
</Button> </Button>
......
...@@ -24,32 +24,52 @@ export async function getPostById(fileDirectory, slug) { ...@@ -24,32 +24,52 @@ export async function getPostById(fileDirectory, slug) {
}) })
); );
return data.filter((e) => e.id == slug); return data.filter((e) => e.id == slug)[0];
} }
export async function getPosts(fileDirectory, page) { async function getAllPosts(fileDirectory) {
const directory = path.join(process.cwd(), fileDirectory); const directory = path.join(process.cwd(), fileDirectory);
const fileNames = await fs.readdir(directory); const fileNames = await fs.readdir(directory);
const dataPromises = fileNames.map(async (fileName) => { const post = await Promise.all(
const id = fileName.replace(/\.md$/, ""); fileNames.map(async (fileName) => {
const fullPath = path.join(fileDirectory, fileName); const id = fileName.replace(/\.md$/, "");
const fileContents = await fs.readFile(fullPath, "utf8"); const fullPath = path.join(fileDirectory, fileName);
const { data, content } = matter(fileContents); const fileContents = await fs.readFile(fullPath, "utf8");
return { const { data } = matter(fileContents);
id, return {
...data, id,
}; ...data,
}); };
})
);
return post;
}
export async function getPosts(fileDirectory, page) {
let post = await getAllPosts(fileDirectory, page);
return getSlicedPost(post, page);
}
const data = await Promise.all(dataPromises); function getSlicedPost(post, page) {
const itemsPerPage = 6; const itemsPerPage = 6;
// Calculate the start and end indices for the current page // Calculate the start and end indices for the current page
const startIndex = (page - 1) * itemsPerPage; const startIndex = (page - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage; const endIndex = startIndex + itemsPerPage;
const slicedData = Array.isArray(data) const slicedData = Array.isArray(post)
? data.slice(startIndex, endIndex) ? post.slice(startIndex, endIndex)
: []; : [];
const response = { data: slicedData, total: data?.length, blogs: data }; const response = { data: slicedData, total: post?.length };
return response; return response;
} }
export async function getPostsBySearch(fileDirectory, page, search) {
const post = await getAllPosts(fileDirectory);
const filterBlog = post.filter((e) => {
return e.title.toLowerCase().includes(search.toLowerCase());
});
let pageNo = filterBlog.length > 6 ? page : page == 1 ? 1 : 0;
const slicedPost = getSlicedPost(filterBlog, pageNo);
return slicedPost;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment