Skip to content

Commit

Permalink
feat: 允许私密 post
Browse files Browse the repository at this point in the history
  • Loading branch information
huayemao committed Jul 23, 2024
1 parent bb2079b commit df1f4e4
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 115 deletions.
6 changes: 5 additions & 1 deletion app/(content)/posts/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PexelsPhoto } from "@/lib/types/PexelsPhoto";
import { markdownExcerpt } from "@/lib/utils";
import nextConfig from "@/next.config.mjs";
import { Metadata } from "next";
import { notFound } from "next/navigation";
import { notFound, redirect } from "next/navigation";
import { join } from "path";

export const revalidate = 300;
Expand Down Expand Up @@ -33,6 +33,10 @@ export async function generateMetadata({
return notFound();
}

if (post.protected) {
return redirect("/protected/" + id);
}

const abstract =
post.excerpt || (await markdownExcerpt(post.content)) + "...";

Expand Down
92 changes: 92 additions & 0 deletions app/(content)/protected/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import Post from "@/components/Post";
import { SITE_META } from "@/constants";
import { getPost, getPostIds, getRecentPosts } from "@/lib/posts";
import { PexelsPhoto } from "@/lib/types/PexelsPhoto";
import { markdownExcerpt } from "@/lib/utils";
import nextConfig from "@/next.config.mjs";
import { Metadata } from "next";
import { notFound } from "next/navigation";
import { join } from "path";

export const revalidate = 300;

export async function generateStaticParams() {
const posts = await getPostIds({ protected: true });
const allPostIds = posts.map((post) => ({
id: String(post.id),
}));
const params =
nextConfig.output === "export" ? allPostIds : allPostIds.slice(0, 15);
return params;
}

export async function generateMetadata({
params,
}: {
params: { id: string };
}): Promise<Metadata> {
// read route params
const id = params.id;
const post = await getPost(parseInt(id as string));

if (!post || !post.content) {
return notFound();
}

const abstract =
post.excerpt || (await markdownExcerpt(post.content)) + "...";

const headerRegex = /^(?!\s)(#{1,6})(.*)/gm;
const headers =
post.content!.match(headerRegex)?.map((e) => e.replace(/^(#+\s+)/, "")) ||
[];

const keywords = post.tags
.map((e) => e?.name || "")
.concat([post.title || ""])
.concat(SITE_META.author.name)
.concat(headers)
.filter((e) => !!e);

return {
title: `${post.title} | ${SITE_META.name}——${SITE_META.description}`,
description: abstract,
abstract: abstract,
keywords,

openGraph: {
description: abstract,
images: [(post.cover_image as PexelsPhoto).src.small],
},
};
}

export default async function page({ params }) {
if (!params.id) {
return;
}

const id = parseInt(params.id as string);

if (Number.isNaN(id)) {
return notFound();
}

const post = await getPost(id);

if (!post) {
return notFound();
}

let posts = await getRecentPosts();

const tmpDir = join(process.cwd(), "tmp");
console.log(tmpDir);

return (
<main className="w-full">
{/* @ts-ignore */}
<Post data={post} recentPosts={posts} />
</main>
);
}
74 changes: 1 addition & 73 deletions app/api/createPost/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import prisma from "@/lib/prisma";
import { createPost } from "@/lib/posts";
import { revalidateHomePage } from "@/lib/utils/retalidate";
import { NextResponse } from "next/server";

Expand Down Expand Up @@ -26,75 +26,3 @@ export async function POST(request: Request) {

return NextResponse.redirect(path, 303);
}

async function createPost(
content: string,
excerpt?: string,
title?: string,
categoryId?: string,
tags?: string[]
) {
const post = await prisma.posts.create({
data: {
excerpt: excerpt as string,
content: content as string,
title: title as string,
created_at: new Date(),
updated_at: new Date(),
posts_category_links: {
create: {
category_id: parseInt(categoryId as string),
},
},
},
});

if (tags?.length) {
const existedTags = await prisma.tags.findMany({
where: {
name: {
in: tags as string[],
},
},
});

const tagsToAdd = tags.filter(
(t) => !existedTags.map((e) => e.name).includes(t as string)
);

await prisma.tags.createMany({
data: tagsToAdd.map((t) => ({
name: t as string,
})),
});

const tagsIds = (
await prisma.tags.findMany({
where: {
name: {
in: tags as string[],
},
},
select: {
id: true,
},
})
).map((e) => e.id);

await prisma.posts.update({
where: {
id: post.id,
},
data: {
tags_posts_links: {
createMany: {
data: tagsIds.map((e) => ({
tag_id: e,
})),
},
},
},
});
}
return post;
}
11 changes: 5 additions & 6 deletions app/api/updatePost/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export async function POST(request: Request) {
const excerpt = (formData.get("excerpt") as string) || undefined;
const title = (formData.get("title") as string) || undefined;
const changePhoto = (formData.get("changePhoto") as string) || undefined;
const protectedStr = (formData.get("protected") as string) || undefined;
const category_id = (formData.get("category_id") as string) || undefined;
const updated_at = (formData.get("updated_at") as string) || undefined;
const created_at = (formData.get("created_at") as string) || undefined;
Expand Down Expand Up @@ -44,21 +45,20 @@ export async function POST(request: Request) {
);
}

const res = await updatePost(
post,
const res = await updatePost(post, {
tags,
id,
content,
excerpt,
title,
changePhoto,
isProtected: protectedStr === "on" ? true : false,
updated_at,
created_at,
category_id
);
categoryId: category_id,
});

await revalidateHomePage(res.id);

await revalidatePath("/posts/" + post.id);
await revalidatePath("/(content)/posts/" + post.id);

Expand All @@ -80,4 +80,3 @@ export async function POST(request: Request) {

return NextResponse.redirect(path, 303);
}

24 changes: 23 additions & 1 deletion components/PostEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
BaseDropdownItem,
BaseSelect,
} from "@shuriken-ui/react";
import { Plus, Save, Settings, TimerReset } from "lucide-react";
import { Lock, Plus, Save, Settings, TimerReset } from "lucide-react";
import Link from "next/link";
import {
FormEventHandler,
Expand Down Expand Up @@ -70,6 +70,7 @@ const handleOnSubmit: FormEventHandler<HTMLFormElement> = (e) => {
export function PostEditor({ post }: PostEditorProps) {
const categories = useContext(CategoriesContext);
const [reserveUpdateTime, setReserveUpdateTime] = useState(false);
const [isProtected, setProtected] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
const [action, setAction] = useState<"upload" | "unicode">("upload");
const [content, setContent] = useState(post?.content || "");
Expand Down Expand Up @@ -260,6 +261,27 @@ export function PostEditor({ post }: PostEditorProps) {
type="datetime-local"
defaultValue={getDateForDateTimeInput(post?.updated_at as Date)}
></input>
<label className="text-stone-400 hover:text-stone-500">
<div className="nui-button-icon nui-button-rounded-md nui-button-small nui-button-default">
<Lock
className={cn("h-4 w-4 cursor-pointer", {
"text-primary-500": isProtected,
})}
/>
</div>
<input
form="post_form"
id="protected"
name="protected"
className="appearance-none m-0 bg-transparent hidden"
type="checkbox"
checked={isProtected}
onChange={(e) => {
setProtected(e.target.checked);
}}
defaultChecked={isProtected}
/>
</label>
</>
)}
{/* @ts-ignore */}
Expand Down
Loading

0 comments on commit df1f4e4

Please sign in to comment.