Commit f16c5e9a by Sakilesh J

finish until the next.js server

parent a2eca5a4
NEXT_PUBLIC_API_URL=http://localhost:4000/
import Button from '@/components/button'; import Button from '@/components/base/Button/index';
const AnotherPage = () => { const AnotherPage = () => {
return ( return (
...@@ -7,7 +7,7 @@ const AnotherPage = () => { ...@@ -7,7 +7,7 @@ const AnotherPage = () => {
<h3 className="text-3xl text-gray-600 font-semibold mb-5 px-5"> <h3 className="text-3xl text-gray-600 font-semibold mb-5 px-5">
You&lsquo;ve landed on another page You&lsquo;ve landed on another page
</h3> </h3>
<Button href="/" size="lg"> <Button href="/" size="md">
Navigate home page Navigate home page
</Button> </Button>
</center> </center>
......
import Blog from "@/pages/blog";
interface blogSiteProps{
params: {
id: number;
}
}
const Blogsite:React.FC<blogSiteProps> = ({params}) => {
return ( <Blog id={Number(params.id)}/> );
}
export default Blogsite;
\ No newline at end of file
import '@/styles/globals.css'; import '@/styles/globals.css';
import ThemeParent from '@/hooks/useTheme';
import Global from '@/layout/GlobalLayout';
import PaginationProvider from '@/hooks/usePagination';
import FilterComponent from '@/hooks/Filter';
interface LayoutProps { interface LayoutProps {
children: React.ReactNode; children: React.ReactNode;
} }
...@@ -11,7 +14,17 @@ export default function RootLayout({ children }: LayoutProps) { ...@@ -11,7 +14,17 @@ export default function RootLayout({ children }: LayoutProps) {
<meta content="width=device-width, initial-scale=1" name="viewport" /> <meta content="width=device-width, initial-scale=1" name="viewport" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
</head> </head>
<body>{children}</body> <body>
<ThemeParent>
<PaginationProvider>
<FilterComponent>
<Global>
{children}
</Global>
</FilterComponent>
</PaginationProvider>
</ThemeParent>
</body>
</html> </html>
); );
} }
import PageNotFound from '@/components/layout/page-not-found'; import PageNotFound from '@/components/layout/PageNotFound/index';
export default PageNotFound; export default PageNotFound;
import Button from '@/components/button'; import Home from "@/pages/Home";
import Image from 'next/image';
const HomePage = () => { const HomePage = () => {
return ( return (
<center className="py-10"> <Home />
<Image
src="/img/nextjs.svg"
alt="Next.js"
width={512}
height={103}
className="w-60 mb-4"
/>
<h3 className="text-3xl text-gray-600 font-semibold mb-5 px-5">
Welcome to Next.js starter template
</h3>
<div className="bg-gray-100 p-5 mb-10">
<p className="mb-3 text-gray-400 font-semibold">
This template is built with
</p>
<div className="flex justify-center gap-5">
<Image
src="/img/tailwind.svg"
alt="Tailwind CSS"
width={512}
height={63}
className="w-40"
/>
<Image
src="/img/typescript.svg"
alt="TypeScript"
width={284}
height={70}
className="w-24"
/>
</div>
</div>
<Button href="/another" size="lg">
Navigate to another page
</Button>
</center>
); );
}; };
export default HomePage; export default HomePage;
\ No newline at end of file
...@@ -12,9 +12,10 @@ const ProfileCard:React.FC<ProfileCardProps> = ({authorImg,author,date}) => { ...@@ -12,9 +12,10 @@ const ProfileCard:React.FC<ProfileCardProps> = ({authorImg,author,date}) => {
<p className="font-sans text-subHeadColor font-semibold text-[12px] sm:text-[14px]">{`${date.toLocaleString('default', { month: 'short' })} ${date.getDate()}, ${date.getFullYear()}.`} <p className="font-sans text-subHeadColor font-semibold text-[12px] sm:text-[14px]">{`${date.toLocaleString('default', { month: 'short' })} ${date.getDate()}, ${date.getFullYear()}.`}
<span className="ml-2 *:inline *:text-[14px] font-semibold "> <span className="ml-2 *:inline *:text-[14px] font-semibold ">
<Image src={Clock} alt="" width={0} height={0} className="mb-[3px] mr-1 w-[15px] h-[15px]" /> <Image src={Clock} alt="" width={0} height={0} className="mb-[3px] mr-1 w-[15px] h-[15px]" />
<p> <span>
{/* {date.getHours()} hrs */}
{date.getMinutes()} mins</p> {date.getMinutes()} mins
</span>
</span> </span>
</p> </p>
</div> </div>
......
import Image from 'next/image' 'use client';
import React, { useRef, useState } from 'react' import React, { useRef, useState } from 'react'
import cn from 'classnames' import cn from 'classnames'
import {Search,Close} from '@/utils/icons' import {Search,Close} from '@/utils/icons'
......
import React from "react" import React from "react"
import Image from "next/image"; import Image from "next/image";
import Link from "next/navigation";
import { profileCardsItems } from "@/types/blog"; import { profileCardsItems } from "@/types/blog";
import ProfileCard from "../Profile-card/ProfileCard"; import ProfileCard from "../Profile-card/ProfileCard";
interface blogcardprops extends profileCardsItems{ interface blogcardprops extends profileCardsItems{
...@@ -8,21 +7,23 @@ interface blogcardprops extends profileCardsItems{ ...@@ -8,21 +7,23 @@ interface blogcardprops extends profileCardsItems{
title?: string; title?: string;
description?: string; description?: string;
id?: number; id?: number;
handleClick:()=>void;
} }
const BlogCard:React.FC<blogcardprops> = ({img,title,description,id,...props}) => { const BlogCard: React.FC<blogcardprops> = ({ img, title, description, id,handleClick, ...props }) => {
return ( return (
<div className="sm:max-w-sm w-full shadow-sm rounded-md cursor-pointer hover:shadow-xl hover:translate-y-[-2px] transition-all duration-300 ease-in-out overflow-hidden <div
dark:*:text-white group h-full"> className="sm:max-w-sm w-full shadow-md rounded-md cursor-pointer hover:shadow-xl hover:translate-y-[-2px] transition-all duration-300 ease-in-out overflow-hidden
dark:*:text-white group h-full" onClick={handleClick}>
{ {
img && img &&
<Image src={img} width={100} height={100} alt="" className="w-full h-[220px] rounded-t-lg object-cover" /> <Image src={img} width={900} height={900} alt="" className="w-full h-[220px] rounded-t-lg object-cover" />
} }
<div className="h-[calc(100%-220px)] p-[1em] sm:p-[1.5em] bg-white flex flex-col dark:bg-[#131617] "> <div className="h-[calc(100%-220px)] p-[1em] sm:p-[1.5em] bg-white flex flex-col dark:bg-[#131617] ">
<h4 className="text-sans font-[700] group-hover:text-primary text-sm sm:text-[18px] my-[.3em] leading-[1.4em]"> <h4 className="text-sans font-[700] group-hover:text-primary text-sm sm:text-[18px] my-[.3em] leading-[1.4em] md:line-clamp-2">
{title} {title}
</h4> </h4>
<p className="text-subHeadColor my-[5px] text-sm sm:text-[17px] mb-[1em] leading-[1.4em] dark:text-gray-400"> <p className="text-subHeadColor my-[5px] text-sm sm:text-[17px] mb-[1em] leading-[1.4em] dark:text-gray-400 md:line-clamp-2">
{description} {description}
</p> </p>
<ProfileCard {...props} /> <ProfileCard {...props} />
......
...@@ -5,6 +5,11 @@ import { blog_data } from '@/utils/Blog_data'; ...@@ -5,6 +5,11 @@ import { blog_data } from '@/utils/Blog_data';
const meta: Meta<typeof BlogCard> = { const meta: Meta<typeof BlogCard> = {
title: 'Top-Level', title: 'Top-Level',
component: BlogCard, component: BlogCard,
argTypes: {
handleClick: {
action:"onClick",
},
}
} }
export default meta; export default meta;
...@@ -22,12 +27,12 @@ export const blog_: Story = { ...@@ -22,12 +27,12 @@ export const blog_: Story = {
} }
export const blog_List__: Story = { export const blog_List__: Story = {
render: () => { render: (args) => {
return ( return (
<div className="flex flex-wrap gap-4 w-full dark:bg-black p-2"> <div className="flex flex-wrap gap-4 w-full dark:bg-black p-2">
{blog_data.map((data, i) => ( {blog_data.map((data, i) => (
<div key={i} className="flex-grow sm:flex-grow-0 sm:w-[calc(50%-1rem)] lg:w-[calc(33.33%-1rem)] xl:w-[calc(25%-1rem)] *:sm:max-w-md *:h-full"> <div key={i} className="flex-grow sm:flex-grow-0 sm:w-[calc(50%-1rem)] lg:w-[calc(33.33%-1rem)] xl:w-[calc(25%-1rem)] *:sm:max-w-md *:h-full">
<BlogCard {...data} /> <BlogCard {...args} {...data} />
</div> </div>
))} ))}
</div> </div>
......
...@@ -18,9 +18,9 @@ interface BlogPageProps{ ...@@ -18,9 +18,9 @@ interface BlogPageProps{
const BlogPage: React.FC<BlogPageProps> = ({ blogTitle, authorDetails,category,readingTime,banner,content,categories }) => { const BlogPage: React.FC<BlogPageProps> = ({ blogTitle, authorDetails,category,readingTime,banner,content,categories }) => {
const { date,author } = authorDetails; const { date,author } = authorDetails;
return ( return (
<div className="max-w-[1200px] mx-auto"> <div className="max-w-[1200px] mx-auto mt-10 px-4">
<div className="lg:px-20"> <div className="lg:px-20">
<h3 className="text-[1.4em] sm:text-4xl md:text-5xl font-libre font-bold sm:font-semibold ">{blogTitle}</h3> <h3 className="text-[1.4em] sm:text-4xl md:text-5xl font-libre font-bold sm:font-semibold dark:text-white">{blogTitle}</h3>
<div className="my-5 *:text-textColor flex gap-4 flex-wrap items-center *:text-sm *:sm:text-md"> <div className="my-5 *:text-textColor flex gap-4 flex-wrap items-center *:text-sm *:sm:text-md">
<p className="font-semibold capitalize dark:text-white">posted on <span className="font-bold text-gray-400 dark:text-white">{date?.toLocaleString('default', { month: 'short' })} {date.getDate()}, {date.getFullYear()}</span> <p className="font-semibold capitalize dark:text-white">posted on <span className="font-bold text-gray-400 dark:text-white">{date?.toLocaleString('default', { month: 'short' })} {date.getDate()}, {date.getFullYear()}</span>
</p> </p>
...@@ -45,7 +45,7 @@ const BlogPage: React.FC<BlogPageProps> = ({ blogTitle, authorDetails,category,r ...@@ -45,7 +45,7 @@ const BlogPage: React.FC<BlogPageProps> = ({ blogTitle, authorDetails,category,r
<ul className="dark:text-gray-400 prose-li:list-none mt-10 flex gap-3 items-center flex-wrap"> <ul className="dark:text-gray-400 prose-li:list-none mt-10 flex gap-3 items-center flex-wrap">
<li className="text-lg">Tags:</li> <li className="text-lg">Tags:</li>
{ {
categories.map((item: string) => (<li className="px-4 hover:bg-primary hover:text-white dark:hover:bg-primary cursor-pointer text-lg py-1 list-none dark:bg-[#2a2a2a] bg-secondary text-textColor dark:text-white w-min rounded-3xl"> categories.map((item: string) => (<li className="px-4 hover:bg-primary hover:text-white dark:hover:bg-primary cursor-pointer text-lg py-1 list-none dark:bg-[#2a2a2a] bg-secondary text-textColor dark:text-white w-min rounded-3xl" key={item}>
{item} {item}
</li>)) </li>))
} }
......
...@@ -15,7 +15,7 @@ type Story = StoryObj<typeof meta>; ...@@ -15,7 +15,7 @@ type Story = StoryObj<typeof meta>;
export const pagination: Story = { export const pagination: Story = {
args: { args: {
size: 7, size: 7,
currentIndex:0, currentPage:1,
}, },
render: (args) => ( render: (args) => (
<div className='dark:bg-black min-h-full p-2'> <div className='dark:bg-black min-h-full p-2'>
......
import Button from "@/components/base/Button/index"; import Button from "@/components/base/Button/index";
import classNames from "classnames";
import React, { useState } from "react"; import React, { useState } from "react";
interface Paginationprops{ interface PaginationProps {
size: number; size: number;
currentIndex: number; currentPage: number;
onChange: (index: number) => void; onChange: (index: number) => void;
} }
const Pagination: React.FC<Paginationprops> = ({ size, currentIndex, onChange }) => {
const [isshow, setisshow] = useState(false) const Pagination: React.FC<PaginationProps> = ({ size, currentPage, onChange }) => {
const [isShow, setIsShow] = useState(false);
const count = 2; const count = 2;
return (
<div className="flex gap-2 flex-wrap "> const handleEllipsisClick = () => {
{ setIsShow(!isShow);
!(currentIndex <0) && };
<>
{ const renderPageButtons = () => {
currentIndex !== 0 && !(currentIndex >= size) && <Button size="sm" onClick={() => onChange(currentIndex - 1)}> const pages = [];
Back
if (currentPage > 1) {
pages.push(
<Button key="prev" size="sm" onClick={() => onChange(currentPage - 1)}>
Previous
</Button> </Button>
);
} }
{
!(currentIndex >= size)&& Array.from({ length: (currentIndex >=size-count+1) || isshow ? size-currentIndex : count}).map((_, index) => { if (currentPage > 2 && !isShow) {
return ( pages.push(
<Button <Button key="1" size="icon" onClick={() => onChange(1)}>
key={index} 1
onClick={() => onChange(index + currentIndex)} </Button>,
size="icon" <Button key="ellipsis-start" size="icon" onClick={handleEllipsisClick}>
isPrimary={currentIndex+index===currentIndex} ...
>
{currentIndex +index + 1}
</Button> </Button>
); );
})
} }
{
(!isshow && size-currentIndex > 2 )&& ( const startPage = isShow ? 1 : Math.max(currentPage, 1);
<React.Fragment> const endPage = isShow ? size : Math.min(currentPage + count, size);
<Button size="icon" onClick={()=>setisshow(!isshow)}>
... for (let i = startPage; i <= endPage; i++) {
const isPrimary = currentPage === i;
pages.push(
<Button key={i} size="icon" isPrimary={isPrimary} onClick={() => onChange(i)}>
{i}
</Button> </Button>
<Button size="icon" onClick={() => onChange(size - 1)}> );
}
if (!isShow && size - currentPage > count+1) {
pages.push(
<Button key="ellipsis-end" size="icon" onClick={handleEllipsisClick}>
...
</Button>,
<Button key={size} size="icon" onClick={() => onChange(size)}>
{size} {size}
</Button> </Button>
</React.Fragment> );
)
} }
{
currentIndex !==size-1 && !(currentIndex >= size) && <Button size="sm" onClick={() => onChange(1 + currentIndex)}> if (currentPage < size) {
pages.push(
<Button key="next" size="sm" onClick={() => onChange(currentPage + 1)}>
Next Next
{/* <Image src={Right_Arrow} alt="arrow" className="w-[16px] h-[16px] mt-[1px]" /> */}
</Button> </Button>
}
</>
}
</div>
); );
} }
return pages;
};
return <div className="flex gap-2 flex-wrap my-10">{renderPageButtons()}</div>;
};
export default Pagination; export default Pagination;
...@@ -12,7 +12,6 @@ interface ButtonProps extends React.HTMLAttributes<HTMLElement> { ...@@ -12,7 +12,6 @@ interface ButtonProps extends React.HTMLAttributes<HTMLElement> {
} }
export default function Button({ children, size, disabled, className, loading, href,isPrimary, block, ...props }: ButtonProps) { export default function Button({ children, size, disabled, className, loading, href,isPrimary, block, ...props }: ButtonProps) {
console.log(isPrimary)
const classes = cn('inline-flex items-center justify-center gap-1 font-sans font-[700] text-textColor leading-2 rounded-xl border-[1px] h-auto dark dark:border-none dark:hover:bg-primary', { const classes = cn('inline-flex items-center justify-center gap-1 font-sans font-[700] text-textColor leading-2 rounded-xl border-[1px] h-auto dark dark:border-none dark:hover:bg-primary', {
'px-4 py-2 text-[18px]': size === 'sm', 'px-4 py-2 text-[18px]': size === 'sm',
'px-6 py-2 text-[22px]': size === 'md', 'px-6 py-2 text-[22px]': size === 'md',
......
const Heading = () => { const Heading = () => {
return (<div> return (
<h3 className="font-libre font-medium text-[45px] text-titleColor mb-2"> <div className="mt-3 dark:*:text-white">
LifeStyle <h3 className="font-libre text-[40px] text-titleColor mb-2 ">
Lifestyle
</h3> </h3>
<p className="text-textColor text-xl ">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nemo, sunt.</p> <p className="text-textColor text-md ">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nemo, sunt.
</div>);
</p>
</div>
);
} }
export default Heading; export default Heading;
\ No newline at end of file
'use client';
import Image from 'next/image'; import Image from 'next/image';
import React, { useEffect, useRef, useState } from 'react'; import React, { useState } from 'react';
import cn from 'classnames'; import cn from 'classnames';
import SearchBar from '@/components/Top-Level/Searchbar/SearchBar'; import SearchBar from '@/components/Top-Level/Searchbar/SearchBar';
import Newspaper from '@/public/Icons/icons-newspaper.svg' import Newspaper from '@/public/Icons/icons-newspaper.svg'
import {Moon,Sun} from "@/utils/icons"; import {Moon,Sun} from "@/utils/icons";
import menu from "@/public/Icons/icons-menu.svg" import menu from "@/public/Icons/icons-menu.svg"
import Link from 'next/link';
interface HeaderProps { interface HeaderProps {
onSearch: (name: string) => void; onSearch: (search:string) => void;
onChangeTheme: () => string; onChangeTheme: () => void;
} }
const Navigation: React.FC<HeaderProps> = ({ onSearch,onChangeTheme }) => { const Navigation: React.FC<HeaderProps> = ({ onSearch,onChangeTheme }) => {
const [isOPen, setisOPen] = useState(false); const [isOPen, setisOPen] = useState(false);
return ( return (
<React.Fragment> <div className="sticky top-0 dark:bg-[#131617] bg-white dark:text-white shadow-md p-4 z-50">
<div className="w-full justify-between flex items-center shadow-md p-4 sticky dark:bg-[black] dark:*:text-white"> <div className="w-full justify-between flex items-center max-w-[1100px] mx-auto">
<div className='flex gap-2 items-center'> <Link className="flex gap-2 items-center" href="/">
<Image src={Newspaper} height={40} width={40} alt="Newspaper" /> <Image src={Newspaper} height={40} width={40} alt="Newspaper" />
<h1 className='font-semibold text-2xl'>NewsBlog</h1> <h1 className="font-semibold text-2xl">NewsBlog</h1>
</div> </Link>
<div className="hidden md:block min-w-[400px]"> <div className="hidden md:block min-w-[400px]">
<SearchBar placeholder='Discover news, articles, and more' className={'font-semibold'} onSearch={onSearch} /> <SearchBar placeholder="Discover news, articles, and more" className="font-semibold" onSearch={onSearch} />
</div> </div>
<div className='hidden md:block'> <div className='ml-auto mr-2 md:m-0'>
<Sun handleClick={onChangeTheme}/> <Sun handleClick={onChangeTheme} />
<Moon handleClick={onChangeTheme}/> <Moon handleClick={onChangeTheme} />
</div>
<div className="block md:hidden w-[40px] h-[40px] rounded-md p-2 bg-primary cursor-pointer *:mr-2" onClick={() => setisOPen(!isOPen)}>
<Image src={menu} alt="Menu" className="w-full h-full" width={100} height={100} />
</div> </div>
<div className='block md:hidden w-[40px] h-[40px] rounded-md p-2 bg-primary cursor-pointer' onClick={()=>setisOPen(!isOPen)}>
<Image src={menu} alt='' className='w-full h-full'/>
</div> </div>
<div className={cn('h-0 overflow-hidden md:hidden transition-all duration-100 ease-in-out container bg-white dark:bg-[#131617] ', {
'h-auto py-2 min-w-full mt-2': isOPen
})}>
<SearchBar placeholder="Discover news, articles, and more" className="font-semibold" onSearch={onSearch} />
</div> </div>
<div className={cn('h-0 overflow-hidden md:hidden transition-all duration-100 ease-in-out container bg-white ', {
'h-[auto] py-2 min-w-full':isOPen
})} >
<SearchBar placeholder='Discover news, articles, and more' className={'font-semibold'} onSearch={onSearch} />
</div> </div>
</React.Fragment>
); );
} }
......
...@@ -6,7 +6,7 @@ export default function PageNotFound() { ...@@ -6,7 +6,7 @@ export default function PageNotFound() {
return ( return (
<div className="flex flex-col justify-center items-center"> <div className="flex flex-col justify-center items-center">
<Image src={FourOhFour} alt="404, Page Not Found!" /> <Image src={FourOhFour} alt="404, Page Not Found!" />
<Button href="/">Back to Home</Button> <Button href="/" size='md'>Back to Home</Button>
</div> </div>
); );
} }
'use client';
import { blog_data } from "@/utils/Blog_data";
import { useState,createContext } from "react";
type FilterContext = {
data:{
id: number;
img: string;
title: string;
description: string;
author: string;
authorImg: string;
date: Date;
}[],
handleFilter:(search:string)=>void
}
export const FilterContext = createContext<FilterContext>({
data: blog_data,
handleFilter:()=>{}
})
interface FilterComponentProps{
children: React.ReactNode;
}
const FilterComponent:React.FC<FilterComponentProps> = ({children}) => {
const [filter, setfilter] = useState(blog_data);
const handleFilter = (search: string) => {
if (search.trim() === "") {
setfilter(blog_data);
} else {
setfilter(blog_data.filter((data) => data.title.toLowerCase().includes(search.toLowerCase())));
}
}
return (<FilterContext.Provider value={{
data: filter,
handleFilter
}}>{children}</FilterContext.Provider> );
}
export default FilterComponent;
\ No newline at end of file
'use client';
import React, { createContext, useState } from "react";
type paginationContextTypes = {
start: number;
end: number;
size: number;
currentPage: number;
handleChangePage: (page: number) => void;
}
interface usePaginationProps {
children: React.ReactNode;
}
export const paginationContext = createContext<paginationContextTypes>({
start: 1,
end: 1,
size: 1,
currentPage: 1,
handleChangePage: () => {},
});
const PaginationProvider:React.FC<usePaginationProps> = ({children}) => {
const [currentPage, setcurrentPage] = useState(1);
const size = 6;
const [start, setstart] = useState(0);
const [end, setend] = useState(size);
const handleChangePage = (page: number) => {
setcurrentPage(page);
setstart((page - 1) * size);
setend(page * size);
}
return (
<paginationContext.Provider value={{
start,
end,
size,
currentPage,
handleChangePage,
}}>
{children}
</paginationContext.Provider>
);
}
export default PaginationProvider;
\ No newline at end of file
'use client';
import React, { createContext, useState } from "react";
interface useThemeProps{
children: React.ReactNode
}
type ThemeContextType = {
theme: 'dark' | 'light';
ToggleTheme: () => void;
};
// Create the context with a default value
export const ThemeContext = createContext<ThemeContextType | null>(null);
const ThemeParent: React.FC<useThemeProps> = ({ children }) => {
const [theme, setTheme] = useState<'light' | 'dark'>('dark');
const ToggleTheme = () => {
if (theme === 'light') setTheme('dark');
else if (theme === 'dark') setTheme('light');
}
return (
<ThemeContext.Provider value={{
theme,
ToggleTheme,
}} >
{children}
</ThemeContext.Provider>
)
}
export default ThemeParent
\ No newline at end of file
'use client';
import Navigation from "@/components/layout/Navigation/Navigation";
import { FilterContext } from "@/hooks/Filter";
import { ThemeContext } from "@/hooks/useTheme";
import React, { useContext } from "react";
interface GlobalLayoutProps{
children: React.ReactNode;
}
const Global:React.FC<GlobalLayoutProps> = ({children}) => {
const ThemeState = useContext(ThemeContext);
const FilterState = useContext(FilterContext);
return (
<div className={`${ThemeState?.theme} `}>
<div className={`bg-light dark:bg-black min-h-screen`}>
<Navigation onSearch={FilterState.handleFilter}
onChangeTheme={ThemeState ? ThemeState?.ToggleTheme : () => { }} />
{children}
</div>
</div>
);
}
export default Global;
\ No newline at end of file
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information. // see https://nextjs.org/docs/basic-features/typescript for more information.
module.exports = { module.exports = {
images: { images: {
domains:['cdn.pixabay.com','images.pexels.com'],
remotePatterns: [ remotePatterns: [
{ {
protocol: 'https', protocol: 'https',
hostname: 's3-ap-southeast-1.amazonaws.com' hostname: 's3-ap-southeast-1.amazonaws.com'
} }
], ],
imageSizes: [64, 128, 256, 576, 768, 992, 1200, 1600, 1920, 2048, 3840] imageSizes: [64, 128, 256, 576, 768, 992, 1200, 1600, 1920, 2048, 3840],
}, },
webpack: (config, { isServer }) => { webpack: (config, { isServer }) => {
if (process.env.ANALYZE && !isServer) { if (process.env.ANALYZE && !isServer) {
...@@ -30,5 +31,5 @@ module.exports = { ...@@ -30,5 +31,5 @@ module.exports = {
]; ];
}, },
poweredByHeader: false, poweredByHeader: false,
compress: false compress: false,
}; };
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"name": "nextjs-starter-template", "name": "nextjs-starter-template",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/typography": "^0.5.13", "@tailwindcss/typography": "^0.5.13",
"@types/node": "^20.11.5", "@types/node": "^20.11.5",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
...@@ -8559,6 +8560,14 @@ ...@@ -8559,6 +8560,14 @@
"@swc/counter": "^0.1.3" "@swc/counter": "^0.1.3"
} }
}, },
"node_modules/@tailwindcss/line-clamp": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.4.tgz",
"integrity": "sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g==",
"peerDependencies": {
"tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
}
},
"node_modules/@tailwindcss/typography": { "node_modules/@tailwindcss/typography": {
"version": "0.5.13", "version": "0.5.13",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz", "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz",
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
"analyze": "cross-env ANALYZE=true next build" "analyze": "cross-env ANALYZE=true next build"
}, },
"dependencies": { "dependencies": {
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/typography": "^0.5.13", "@tailwindcss/typography": "^0.5.13",
"@types/node": "^20.11.5", "@types/node": "^20.11.5",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
......
'use client'
import Heading from "@/components/base/Heading/Heading";
import BlogCard from "@/components/Top-Level/blog-card/BlogCard";
import Pagination from "@/components/Top-Level/pagination/pagination";
import { FilterContext } from "@/hooks/Filter";
import { paginationContext } from "@/hooks/usePagination";
import { useRouter } from "next/navigation";
import { useContext, useEffect, useState } from "react";
const Home = () => {
const [isMounted, setisMounted] = useState(false)
const { size, currentPage, start, end, handleChangePage } = useContext(paginationContext);
const router = useRouter();
const {data} = useContext(FilterContext);
useEffect(() => {
setisMounted(true);
}, [])
if (!isMounted) {
return null
}
return (
<div className="max-w-[1100px] mx-auto px-2 ">
<Heading />
<div className="flex flex-wrap gap-6 w-full dark:bg-black mt-4">
{
data.length === 0 && <h2 className=" capitalize dark:text-white text-center w-full text-2xl font-semibold py-5">no Data found</h2>
}
{data?.slice(start,end).map((data) => (
<div key={data.id} className="flex-grow sm:flex-grow-0 sm:w-[calc(50%-1rem)]
lg:w-[calc(33.33%-1rem)] *:sm:max-w-full *:h-full">
<BlogCard {...data} handleClick={() => {
router.push(`/blog/${data.id}`)
}}/>
</div>
))}
</div>
<center className="w-full p-6 flex justify-center ">
<Pagination size={Math.ceil(data
.length / size)} onChange={handleChangePage} currentPage={currentPage} />
</center>
</div >
);
}
export default Home;
\ No newline at end of file
import BlogPage from '@/components/Top-Level/blog-page/Blogpage'
import { pageData } from '@/utils/Data';
interface BlogProps{
id:number;
}
const Blog: React.FC<BlogProps> = ({ id }) => {
const data = pageData[id - 1];
return (
<BlogPage {...data} />
)
}
export default Blog
\ No newline at end of file
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
head,body,:root{
width: 100%;
min-height: 100%;
}
@font-face { @font-face {
font-family: hind; font-family: hind;
src: url('https://fonts.googleapis.com/css2?family=Hind:wght@300;400;500;600;700&display=swap'); src: url('https://fonts.googleapis.com/css2?family=Hind:wght@300;400;500;600;700&display=swap');
......
...@@ -5,7 +5,9 @@ const config: Config = { ...@@ -5,7 +5,9 @@ const config: Config = {
'./pages/**/*.{js,ts,jsx,tsx,mdx}', './pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}', './app/**/*.{js,ts,jsx,tsx,mdx}',
'./utils/**/*.{js,ts,jsx,tsx,mdx}' './utils/**/*.{js,ts,jsx,tsx,mdx}',
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./layout/**/*.{js,ts,jsx,tsx,mdx}'
], ],
darkMode: 'class', // Using 'class' instead of 'selector' for dark mode darkMode: 'class', // Using 'class' instead of 'selector' for dark mode
theme: { theme: {
...@@ -32,6 +34,7 @@ const config: Config = { ...@@ -32,6 +34,7 @@ const config: Config = {
}, },
plugins: [ plugins: [
require('@tailwindcss/typography'), require('@tailwindcss/typography'),
require('@tailwindcss/line-clamp'),
], ],
}; };
......
This diff is collapsed. Click to expand it.
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