feat(blog) add footer for post reading part

This commit is contained in:
lumither committed 2024-07-26 19:30:43 +08:00
1 parent dbe84bc9f4
commit 36f686c563
11 files changed
+180 -25

No files matched your search

+1 -1
View File
@@ -7,7 +7,7 @@ function Layout({
}) {
return (
// <div className={ 'flex flex-auto p-7 pl-2 md:pl-7 items-stretch justify-center' }>
<div className={ 'flex flex-auto p-7 pl-2 md:pl-7 w-full justify-center' }>
<div className={ 'flex flex-auto p-7 pl-2 lg:pl-7 w-full justify-center' }>
{ children }
</div>
);
+90
View File
@@ -0,0 +1,90 @@
import React from 'react';
import MinifyPostCard from '@/app/blog/post/[id]/MinifyPostCard';
import Link from 'next/link';
import { FaCreativeCommons } from 'react-icons/fa6';
type Props = {
post: any
}
const Footer = (props: Props) => {
const { post } = props;
const header_img = post['header_img'];
const adjacent_posts = post['adj'];
const prev_post = adjacent_posts['prev'];
const next_post = adjacent_posts['next'];
const link = post['meta']['link'] ?? `https://lumither.com/blog/post/${ post['meta']['id'] }`;
const author = post['meta']['author'] ?? 'Tao';
const author_link = post['meta']['author_link'] ?? '/about';
const post_date = new Date(post['first_update']);
const update_date = new Date(post['last_update']);
const cc = post['meta']['cc'] ?? 'by-nc-sa';
return (
<div className={ `w-full` }>
<div className={ 'flex transition bg-zinc-300/80 dark:bg-gray-600/25' }>
<div className={ `p-8 w-full` }>
<div className={ 'flex flex-col space-y-4 relative' }>
<div className={ 'z-[2]' }>
<p className={ 'text-xl font-bold' }>{ post['meta']['title'] }</p>
<Link href={ link }>
<p className={ 'text-sm underline decoration-indigo-500 dark:decoration-sky-500' }>{ link }</p>
</Link>
</div>
<div className={ 'z-[2] flex flex-row flex-wrap gap-x-7 gap-y-2' }>
<div>
<p className={ 'text-lg font-bold' }>Author</p>
<Link href={ author_link }>
<p className={ 'underline decoration-indigo-500 dark:decoration-sky-500' }>{ author }</p>
</Link>
</div>
<div>
<p className={ 'text-lg font-bold' }>Posted on</p>
<p>{ post_date.toLocaleString('default', {
month: `long`,
day: `numeric`,
year: `numeric`
}) }</p>
</div>
<div>
<p className={ 'text-lg font-bold' }>Updated on</p>
<p>{ update_date.toLocaleString('default', {
month: `long`,
day: `numeric`,
year: `numeric`
}) }</p>
</div>
<div>
<p className={ 'text-lg font-bold' }>Published under</p>
<Link href={ `https://creativecommons.org/licenses/${ cc }/4.0/` }>
<p className={ 'underline decoration-indigo-500 dark:decoration-sky-500' }>{ `CC ${ cc.toUpperCase() } 4.0` }</p>
</Link>
</div>
</div>
<FaCreativeCommons size={ '80px' }
className={ 'absolute inset-y-0 right-0 opacity-50 brightness-75 z-0' } />
</div>
</div>
</div>
<div className={ `flex justify-center` }>
<div className={ `w-full shadow-2xl ` }>
<div className={ `flex flex-col md:flex-row w-full` }>
{
next_post &&
<MinifyPostCard post={ next_post } desc={ 'prev' }></MinifyPostCard>
}
{
prev_post &&
<MinifyPostCard post={ prev_post } desc={ 'next' }></MinifyPostCard>
}
</div>
</div>
</div>
</div>
);
};
export default Footer;
+9 -9
View File
@@ -10,15 +10,15 @@ type Props = {
const Headers = (props: Props) => {
let post = props.post;
let title = (post as any)['title'];
let sub_title = (post as any)['sub_title'];
let title = post['title'];
let sub_title = post['sub_title'];
// let summary = (post as any)['summary'];
let category = (post as any)['category'];
let tags = (post as any)['tags'];
let last_update = new Date((post as any)['last_update']);
let first_update = new Date((post as any)['first_update']);
let post_id = (post as any)['post_id'];
let header_img = (post as any)['header_img'];
let category = post['category'];
let tags = post['tags'];
// let last_update = new Date((post as any)['last_update']);
let first_update = new Date(post['first_update']);
// let post_id = (post as any)['post_id'];
let header_img = post['header_img'];
return (
<>
@@ -39,7 +39,7 @@ const Headers = (props: Props) => {
<div
className={ header_img !== '' ?
'mx-8 -mt-16 backdrop-blur bg-zinc-300/80 dark:bg-gray-600/25 rounded-2xl z-30'
'mx-8 -mt-16 backdrop-blur transition bg-zinc-300/80 dark:bg-gray-600/25 rounded-2xl z-30'
: 'mx-6 mt-6'
}>
<div className={ `p-4` }>
@@ -0,0 +1,56 @@
import React from 'react';
import { Card, CardFooter, CardHeader } from '@nextui-org/card';
import Image from 'next/image';
import Link from 'next/link';
type Props = {
post: any
desc: string
}
const MinifyPostCard = (props: Props) => {
const { post, desc } = props;
const img_url = post['header_img'] as string;
return (
<div className={ 'w-full transition hover:brightness-75' }>
<Card isFooterBlurred
className="w-full h-[300px] shadow-none border-0 rounded-none overflow-hidden"
as={ Link }
isPressable
href={ `/blog/post/${ post['id'] }` }
>
<CardHeader className="absolute z-10 top-1 flex-col items-start">
<p className={ `text-tiny uppercase font-bold ${ img_url ? 'text-white/60' : 'text-black/60 dark:text-white/60' }` }>{ desc }</p>
</CardHeader>
{ img_url &&
<div>
<Image
className={ 'object-cover object-center ' }
src={ img_url }
alt={ post.title }
fill
/>
<CardFooter
className="absolute transition-colors bg-zinc-300/80 dark:bg-gray-600/25 dark:backdrop-brightness-75 bottom-0 justify-between rounded-none">
<div>
<p className="text-2xl font-bold">{ post['title'] }</p>
<p className="">{ post['sub_title'] }</p>
</div>
</CardFooter>
</div>
}
{ !img_url &&
<div className={ 'h-full grid p-6 place-content-center' }>
<div className={ 'flex flex-row items-center text-center max-h-fit' }>
<p className={ 'text-3xl font-bold' }>{ post['title'] }</p>
<div className={ 'h-full w-1 mx-2 bg-zinc-500 dark:bg-zinc-400' }></div>
<p className={ 'text-xl' }>{ post['sub_title'] }</p>
</div>
</div>
}
</Card>
</div>
);
};
export default MinifyPostCard;
+8 -1
View File
@@ -10,6 +10,7 @@ import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import rehypeRaw from 'rehype-raw';
import rehypeSanitize from 'rehype-sanitize';
import Headers from '@/app/blog/post/[id]/Headers';
import Footer from '@/app/blog/post/[id]/Footer';
type Props = {
id: string
@@ -37,7 +38,7 @@ async function PostCard(props: Props) {
<div>
<Card className={ `max-w-full relative` }>
{/* card headers*/ }
{/* card headers */ }
<Headers post={ post_data } />
{/* card body */ }
@@ -87,6 +88,12 @@ async function PostCard(props: Props) {
} }
>{ (post_data as any)['content'] }</Markdown>
</CardBody>
{/* card footer */ }
<Footer post={ post_data } />
</Card>
</div>
);
+1 -1
View File
@@ -18,7 +18,7 @@ export default function RootLayout({
}>) {
return (
<html lang="en" suppressHydrationWarning>
<body className={ `dark:bg-[#282830] min-h-screen` }>
<body className={ `transition duration-300 dark:bg-[#282830] min-h-screen` }>
<NextThemesProvider attribute="class" defaultTheme="dark">
<div className={ `justify-center flex flex-row w-full max-w-full` }>
<Navbar />
+8 -8
View File
@@ -89,7 +89,7 @@ function Navbar() {
}, [ path ]);
const minMobileWidth: number = 768;
const minMobileWidth: number = 1024;
const [ isMobile, setIsMobile ] = useState(false);
useEffect(() => {
const updateMobileWidth = () => {
@@ -111,9 +111,9 @@ function Navbar() {
return (
<>
<div
className={ `flex flex-col min-w-[50px] md:min-w-[256px] mr-0 md:mr-2 ml-2 md:ml-8 min-h-dvh pt-8 sticky` }>
className={ `flex flex-col min-w-[50px] lg:min-w-[256px] mr-0 lg:mr-2 ml-2 lg:ml-8 min-h-dvh pt-8 sticky` }>
<div className={ `fixed min-h-screen h-full` }>
<div className={ `hidden md:block` }>
<div className={ `hidden lg:block` }>
<div className={ `flex justify-center items-center my-7` }>
<NextImage
src={ 'https://oss.lumither.com/blog/pictures/compr/1717153492846703409_avatar.webp' }
@@ -132,7 +132,7 @@ function Navbar() {
</div>
<div>
<ul className={ `flex flex-col space-y-2 md:space-y-0 md:flex-row items-center my-4 md:space-x-2` }>
<ul className={ `flex flex-col space-y-2 lg:space-y-0 lg:flex-row items-center my-4 lg:space-x-2` }>
{
connections.map((conn, key) => (
<li key={ key }>
@@ -154,7 +154,7 @@ function Navbar() {
</div>
<div
className={ `flex justify-center md:justify-start w-full mt-8 ml-0 md:-ml-3` }>
className={ `flex justify-center lg:justify-start w-full mt-8 ml-0 lg:-ml-3` }>
<ul className={ `flex flex-col space-y-2 w-full` }>
{
entries.map((meta, key) => (
@@ -165,11 +165,11 @@ function Navbar() {
color={ `default` }
fullWidth
isIconOnly={ isMobile }
className={ 'flex md:justify-start w-fit md:w-full' }
className={ 'flex lg:justify-start w-fit lg:w-full' }
aria-label={ `navbar: ${ meta.display_name }` }
href={ meta.href }>
{ meta.icon }
<p className={ `font-bold hidden md:block` }>{ meta.display_name }</p>
<p className={ `font-bold hidden lg:block` }>{ meta.display_name }</p>
</Button>
</li>
))
@@ -177,7 +177,7 @@ function Navbar() {
</ul>
</div>
<div className={ `mt-8 flex md:hidden justify-center w-full` }>
<div className={ `mt-8 flex lg:hidden justify-center w-full` }>
<p className={ `text-center sideways-lr font-bold text-2xl text-zinc-500 dark:text-zinc-400` }>
{ shownPath }
</p>
+1 -1
View File
@@ -33,7 +33,7 @@ function ThemeSwitcher() {
}
} }
></Switch>
<p className={ `font-bold hidden md:block` }>{ `Toggle Theme` }</p>
<p className={ `font-bold hidden lg:block` }>{ `Toggle Theme` }</p>
</div>
</div>
);
+1
View File
@@ -33,6 +33,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.4.19",
"eslint": "^8",
"eslint-config-next": "14.2.2",
"postcss": "^8",
+4 -3
View File
@@ -1,8 +1,9 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};
export default config;