Skip to content

Commit dc14a33

Browse files
committed
add: Last Edited Date
1 parent 0d19448 commit dc14a33

File tree

8 files changed

+67
-15
lines changed

8 files changed

+67
-15
lines changed

app/articles/[...slug]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const ArticlePage = ({ params }: ArticlePageProps) => {
6262
<div className={"min-h-screen backdrop-blur-3xl bg-slate-50/50 dark:bg-gray-800/70"}>
6363
<div className={"flex min-h-[200px] md:min-h-[300px] rounded-b-2xl overflow-hidden"}
6464
style={{backgroundImage: 'url(' + article.image +')', backgroundSize: 'cover'}}>
65-
<ArticlesPageHeading title={article.title} date={article.date} tags={article.tags}/>
65+
<ArticlesPageHeading article={article}/>
6666
</div>
6767
<div className={cn(
6868
"pb-8 mx-4 md:mx-auto lg:px-4",

components/Tags.tsx

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,55 @@
11
import { cn } from "@/lib/utils";
2-
import { format, parseISO } from "date-fns";
2+
import { parseISO, differenceInDays, format } from 'date-fns';
3+
import * as Tooltip from "@radix-ui/react-tooltip";
34
import { HiHashtag } from "react-icons/hi";
45
import Link from "next/link";
56

67
type DateTagProps = {
78
date: string;
9+
lastEdited: string;
810
}
911

10-
export function DateTag({ date }: DateTagProps) {
12+
export function DateTag({ date, lastEdited }: DateTagProps) {
13+
const parsedDate = parseISO(date);
14+
const parsedLastEdited = parseISO(lastEdited);
15+
const daysDifference = differenceInDays(parsedLastEdited, parsedDate);
16+
17+
if (daysDifference > 1) {
18+
return (
19+
<Tooltip.Provider>
20+
<Tooltip.Root>
21+
<Tooltip.Trigger asChild>
22+
<div className={"bg-accent_color/50 dark:bg-accent_color-dark/70 rounded-md"}>
23+
<div className={"text-xs py-1 px-2"} suppressHydrationWarning={true}>
24+
Posted on {format(parsedDate, 'LLLL d, yyyy')} (Edited)
25+
</div>
26+
</div>
27+
</Tooltip.Trigger>
28+
<Tooltip.Portal>
29+
<Tooltip.Content
30+
className="bg-accent_color/50 dark:bg-accent_color-dark/70 rounded-md"
31+
sideOffset={5}
32+
suppressHydrationWarning={true}
33+
side={"right"}
34+
>
35+
<div className={"text-xs py-1 px-2"} suppressHydrationWarning={true}>
36+
Last edited on {format(parsedLastEdited, 'LLLL d, yyyy')}
37+
</div>
38+
<Tooltip.Arrow className="fill-accent_color/50 dark:fill-accent_color-dark/70" />
39+
</Tooltip.Content>
40+
</Tooltip.Portal>
41+
</Tooltip.Root>
42+
</Tooltip.Provider>
43+
)
44+
}
45+
1146
return (
1247
<div className={"bg-accent_color/50 dark:bg-accent_color-dark/70 rounded-md"}>
1348
<div className={"text-xs py-1 px-2"} suppressHydrationWarning={true}>
14-
Posted on {format(parseISO(date), 'LLLL d, yyyy')}
49+
Posted on {format(parsedDate, 'LLLL d, yyyy')}
1550
</div>
1651
</div>
17-
)
52+
);
1853
}
1954

2055
export function NoTag() {

components/article/ArticleCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default function ArticleCard({ article, idx }: ArticleCardProps) {
4545

4646
<div className="w-full md:w-5/12 p-4 lg:px-8">
4747
<div className={"flex mb-2"}>
48-
<DateTag date={article.date}></DateTag>
48+
<DateTag date={article.date} lastEdited={article.lastEdited}/>
4949
</div>
5050
<div className={"flex mb-3"}>
5151
{(() => {

components/article/ArticlesPageHeading.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import { motion } from "framer-motion";
44
import { DateTag, NoTag, Tag } from "@/components/Tags";
5+
import { type Article } from "contentlayer/generated";
56

6-
interface ArticlePageHeadingProps {
7-
title: string;
8-
date: string;
9-
tags?: string[];
7+
interface ArticlesPageHeadingProps {
8+
article: Article; // Assuming you have a type named 'Article'
109
}
1110

12-
export default function ArticlesPageHeading({ title, date, tags }: ArticlePageHeadingProps) {
11+
export default function ArticlesPageHeading({ article }: ArticlesPageHeadingProps) {
12+
const { title, date, lastEdited, tags } = article;
13+
1314
let FADE_DOWN_ANIMATION_VARIANTS = {
1415
hidden: { opacity: 0, y: -10 },
1516
show: { opacity: 1, y: 0, transition: { type: "spring" } },
@@ -53,7 +54,7 @@ export default function ArticlesPageHeading({ title, date, tags }: ArticlePageHe
5354
className={"flex mb-2"}
5455
variants={FADE_DOWN_ANIMATION_VARIANTS}
5556
>
56-
<DateTag date={date}/>
57+
<DateTag date={date} lastEdited={lastEdited}/>
5758
</motion.div>
5859
<motion.div
5960
className={"flex"}

components/search/SearchResults.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function ArticleCard({ article }: ArticleCardProps) {
2828
{article.excerpt}
2929
</p>
3030
<div className={"flex space-x-1"}>
31-
<DateTag date={article.date} />
31+
<DateTag date={article.date} lastEdited={article.lastEdited}/>
3232
{(() => {
3333
if (!article.tags || article.tags.length === 0) {
3434
return (

contentlayer.config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { remarkCodeHike } from "@code-hike/mdx";
33
import remarkGfm from "remark-gfm";
44
import rehypeSlug from "rehype-slug";
55
import rehypeAutolinkHeadings, { type Options as AutolinkOptions } from 'rehype-autolink-headings';
6+
import { execSync } from "child_process";
67

78
const computedFields: ComputedFields = {
89
slug: {
@@ -31,6 +32,20 @@ export const Article = defineDocumentType(() => ({
3132
type: 'string',
3233
resolve: (article) => article.image = article.image + "?r=" + Math.random(),
3334
},
35+
lastEdited: {
36+
type: 'string',
37+
resolve: (article) => {
38+
try {
39+
const filePath = `./content/${article._raw.flattenedPath}.mdx`;
40+
const dateStr = execSync(`git log -1 --format="%ad" -- ${filePath}`, {
41+
encoding: 'utf-8'
42+
});
43+
return new Date(dateStr).toISOString();
44+
} catch (e) {
45+
return new Date(article.date).toISOString();
46+
}
47+
}
48+
},
3449
...computedFields,
3550
},
3651
}))

lib/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { clsx, type ClassValue } from 'clsx';
2-
import { twMerge } from 'tailwind-merge';
1+
import { type ClassValue, clsx } from "clsx";
2+
import { twMerge } from "tailwind-merge";
33

44
/** Utility function to merge Tailwind classes with clsx and tailwind-merge */
55
export function cn(...inputs: ClassValue[]) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"@radix-ui/react-dialog": "^1.0.4",
3030
"@radix-ui/react-dropdown-menu": "^2.0.5",
3131
"@radix-ui/react-navigation-menu": "^1.1.3",
32+
"@radix-ui/react-tooltip": "^1.0.6",
3233
"@tailwindcss/typography": "^0.5.9",
3334
"@types/mdx": "^2.0.5",
3435
"@types/node": "20.2.5",

0 commit comments

Comments
 (0)