-
);
-}
+};
export default About;
diff --git a/frontend/app/about/website/page.tsx b/frontend/app/about/website/page.tsx
new file mode 100644
index 0000000..0fc5d5a
--- /dev/null
+++ b/frontend/app/about/website/page.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import MarkdownRenderer from '@/app/public/MarkdownRenderer';
+import { fetchText } from '@/app/fetch';
+
+const Website = async () => {
+ return (
+
+ );
+};
+export default Website;
diff --git a/frontend/app/archive/page.tsx b/frontend/app/archive/page.tsx
deleted file mode 100644
index 9991bdd..0000000
--- a/frontend/app/archive/page.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import ConstructionPlaceHolder from '@/components/ConstructionPlaceHolder';
-
-const Archive = () => {
- return (
-
- );
-};
-
-export default Archive;
diff --git a/frontend/app/blog/layout.tsx b/frontend/app/blog/layout.tsx
index 058d39a..2c3ea28 100644
--- a/frontend/app/blog/layout.tsx
+++ b/frontend/app/blog/layout.tsx
@@ -6,9 +6,10 @@ function Layout({
children: React.ReactNode;
}) {
return (
- //
- { children }
+
+ { children }
+
);
}
diff --git a/frontend/app/blog/post/[id]/ButtonGoBack.tsx b/frontend/app/blog/post/[id]/ButtonGoBack.tsx
new file mode 100644
index 0000000..924e2f8
--- /dev/null
+++ b/frontend/app/blog/post/[id]/ButtonGoBack.tsx
@@ -0,0 +1,21 @@
+'use client';
+
+import React from 'react';
+import { useRouter } from 'next/navigation';
+import { Button } from '@nextui-org/react';
+import { IoArrowBackOutline } from 'react-icons/io5';
+
+const ButtonGoBack = () => {
+ const router = useRouter();
+
+ return (
+
}
+ variant={ 'light' }
+ onClick={ () => router.back() }
+ >
+ { 'Back' }
+
+ );
+};
+export default ButtonGoBack;
diff --git a/frontend/app/blog/post/[id]/PostCard.tsx b/frontend/app/blog/post/[id]/PostCard.tsx
index 817c28e..056f3d1 100644
--- a/frontend/app/blog/post/[id]/PostCard.tsx
+++ b/frontend/app/blog/post/[id]/PostCard.tsx
@@ -1,16 +1,9 @@
import React from 'react';
-import Markdown from 'react-markdown';
import { Card, CardBody } from '@nextui-org/card';
-import remarkGfm from 'remark-gfm';
-import remarkToc from 'remark-toc';
-import remarkFrontmatter from 'remark-frontmatter';
-import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
-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';
import { fetchNocturneApi } from '@/app/blog/api';
+import MarkdownRenderer from '@/app/public/MarkdownRenderer';
type Props = {
id: string
@@ -31,55 +24,15 @@ async function PostCard(props: Props) {
{/* card body */ }
-
-
- {
- String((children as any)['props']['children']).replace(/\n$/, '')
- }
-
-
- );
- } else {
- return (
-
-
- { children }
-
-
- );
- }
- }
- } }
- >{ ret['content'] }
+
+
+ { ret['content'] }
+
+
{/* card footer */ }
-
diff --git a/frontend/app/blog/post/[id]/page.tsx b/frontend/app/blog/post/[id]/page.tsx
index 8d1c710..13ea3b2 100644
--- a/frontend/app/blog/post/[id]/page.tsx
+++ b/frontend/app/blog/post/[id]/page.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import PostCard from '@/app/blog/post/[id]/PostCard';
import { MotionDiv } from '@/app/public/MotionDiv';
+import ButtonGoBack from '@/app/blog/post/[id]/ButtonGoBack';
function BlogReader({ params }: { params: { id: string } }) {
@@ -14,6 +15,9 @@ function BlogReader({ params }: { params: { id: string } }) {
+
+
+
);
}
diff --git a/frontend/app/fetch.ts b/frontend/app/fetch.ts
new file mode 100644
index 0000000..5720441
--- /dev/null
+++ b/frontend/app/fetch.ts
@@ -0,0 +1,17 @@
+export async function fetchText(url: string, ttl: number = 600) {
+ const res = await fetch(url, {
+ next: {
+ revalidate: ttl
+ }
+ });
+ return await res.text();
+}
+
+export async function fetchJson(url: string, ttl: number = 600) {
+ const res = await fetch(url, {
+ next: {
+ revalidate: ttl
+ }
+ });
+ return await res.json();
+}
diff --git a/frontend/app/friends/layout.tsx b/frontend/app/friends/layout.tsx
new file mode 100644
index 0000000..37dad5b
--- /dev/null
+++ b/frontend/app/friends/layout.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+
+function Layout({
+ children
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+ { children }
+
+ );
+}
+
+export default Layout;
diff --git a/frontend/app/friends/page.tsx b/frontend/app/friends/page.tsx
new file mode 100644
index 0000000..64017d9
--- /dev/null
+++ b/frontend/app/friends/page.tsx
@@ -0,0 +1,85 @@
+import React from 'react';
+import { fetchJson } from '@/app/fetch';
+import { Card, CardBody } from '@nextui-org/react';
+import Image from 'next/image';
+import Link from 'next/link';
+
+export default async function Friends() {
+
+ let list = await fetchJson('https://raw.githubusercontent.com/Lumither/friends/master/friends.json');
+
+ const listLength = list.length;
+ const listMaxIdx = listLength - 1;
+ const listIsOdd = listLength % 2 !== 0;
+
+ return (
+
+
+
+
+
{ 'Though far apart, kin at heart' }
+
+
+
+ {
+ list.map((friend: any, key: number) => (
+ -
+
+
+
+
+
+
{ friend['title'] }
+ { (friend['name'] === undefined || friend['name'].isNull) ??
+
{ `@ ${ friend['name'] }` }
}
+ { (friend['desc'] === undefined || friend['desc'].isNull) ??
+
{ friend['desc'] }
}
+
+
+
+
+
+
+ ))
+ }
+
+
+
+
想要成为好伙伴嘛,向这里发起PR吧
+
+
+ );
+}
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx
index 4cfc2ca..e9f70cd 100644
--- a/frontend/app/page.tsx
+++ b/frontend/app/page.tsx
@@ -3,10 +3,8 @@ import React from 'react';
export default function Home() {
return (
-
-
-
-
-
+
+
+
);
}
diff --git a/frontend/app/public/MarkdownRenderer.tsx b/frontend/app/public/MarkdownRenderer.tsx
new file mode 100644
index 0000000..f3726ea
--- /dev/null
+++ b/frontend/app/public/MarkdownRenderer.tsx
@@ -0,0 +1,64 @@
+import React from 'react';
+import Markdown from 'react-markdown';
+import remarkGfm from 'remark-gfm';
+import remarkToc from 'remark-toc';
+import remarkFrontmatter from 'remark-frontmatter';
+import rehypeRaw from 'rehype-raw';
+import rehypeSanitize from 'rehype-sanitize';
+import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
+import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
+
+const MarkdownRenderer = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+
+
+ {
+ String((children as any)['props']['children']).replace(/\n$/, '')
+ }
+
+
+ );
+ } else {
+ return (
+
+
+ { children }
+
+
+ );
+ }
+ }
+ } }
+ >
+ {
+ children as any
+ }
+
+
+ );
+};
+export default MarkdownRenderer;
diff --git a/frontend/app/public/css/article.css b/frontend/app/public/css/article.css
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/app/tags/page.tsx b/frontend/app/tags/page.tsx
deleted file mode 100644
index a343f54..0000000
--- a/frontend/app/tags/page.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import ConstructionPlaceHolder from '@/components/ConstructionPlaceHolder';
-
-const Tags = () => {
- return (
-
-
-
- );
-};
-
-export default Tags;
diff --git a/frontend/components/Navbar.tsx b/frontend/components/Navbar.tsx
index cfa2e53..a310640 100644
--- a/frontend/components/Navbar.tsx
+++ b/frontend/components/Navbar.tsx
@@ -3,16 +3,7 @@
import React, { useEffect, useState } from 'react';
import { Button } from '@nextui-org/react';
import NextImage from 'next/image';
-import {
- IoFileTrayFull,
- IoHome,
- IoInformationCircle,
- IoLogoGithub,
- IoMail,
- IoPencil,
- IoPricetags,
- IoSearch
-} from 'react-icons/io5';
+import { IoHome, IoInformationCircle, IoLink, IoLogoGithub, IoMail, IoPencil, IoSearch } from 'react-icons/io5';
import Link from 'next/link';
import ThemeSwitcher from '@/components/ThemeSwitcher';
import { usePathname } from 'next/navigation';
@@ -34,14 +25,9 @@ const entries: { display_name: string; href: string; icon: React.ReactNode }[] =
href: '/blog'
},
{
- icon:
,
- display_name: 'Tags',
- href: '/tags'
- },
- {
- icon:
,
- display_name: 'Archive',
- href: '/archive'
+ icon:
,
+ display_name: 'Friends',
+ href: '/friends'
},
{
icon:
,
@@ -116,7 +102,7 @@ function Navbar() {