From 112dcc73b4c16871ecd1104eb5ab6fbd574ceabb Mon Sep 17 00:00:00 2001 From: DefectingCat Date: Mon, 24 Oct 2022 17:49:54 +0800 Subject: [PATCH] Add projects page Update project item styles Update project page layout Fix about page loading backgourd color wrong in dark mode Add project page --- .editorconfig | 2 +- .prettierrc.json | 3 +- Dockerfile | 2 +- components/NavBar.tsx | 7 ++- components/RUA/tab/index.tsx | 10 ++-- components/mdx/Pre.tsx | 12 +--- components/pages/ProjectCard.tsx | 54 ++++++++++++++++++ pages/about.tsx | 5 +- pages/p/[slug].tsx | 20 +++---- pages/projects.tsx | 94 ++++++++++++++++++++++++++++++++ 10 files changed, 176 insertions(+), 33 deletions(-) create mode 100644 components/pages/ProjectCard.tsx create mode 100644 pages/projects.tsx diff --git a/.editorconfig b/.editorconfig index ebe51d3..95405c1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,4 +9,4 @@ indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = false -insert_final_newline = false \ No newline at end of file +insert_final_newline = false diff --git a/.prettierrc.json b/.prettierrc.json index 937375d..81d0180 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,4 +1,5 @@ { "semi": true, - "singleQuote": true + "singleQuote": true, + "editorconfig": true } diff --git a/Dockerfile b/Dockerfile index fa56e14..dc5ee33 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,4 +58,4 @@ EXPOSE 3000 ENV PORT 3000 -CMD ["node", "server.js"] \ No newline at end of file +CMD ["node", "server.js"] diff --git a/components/NavBar.tsx b/components/NavBar.tsx index 27041c6..c09cdf3 100644 --- a/components/NavBar.tsx +++ b/components/NavBar.tsx @@ -21,11 +21,16 @@ const txtMenu = [ }, { id: 2, + name: 'Projects', + path: '/projects', + }, + { + id: 3, name: 'Gists', path: '/gists', }, { - id: 3, + id: 4, name: 'About', path: '/about', }, diff --git a/components/RUA/tab/index.tsx b/components/RUA/tab/index.tsx index 7a10210..9dd2110 100644 --- a/components/RUA/tab/index.tsx +++ b/components/RUA/tab/index.tsx @@ -15,12 +15,10 @@ const Tab = ({ defaultValue, children }: Props) => { // Pass current selected state to child const childrenWithProps = React.Children.map(children, (child) => { - if (React.isValidElement(child)) { - return React.cloneElement(child, { - showContent: child.props.value === currentValue, - }); - } - return child; + if (!React.isValidElement(child)) return child; + return React.cloneElement(child, { + showContent: child.props.value === currentValue, + }); }); return ( diff --git a/components/mdx/Pre.tsx b/components/mdx/Pre.tsx index 270ad05..57ff559 100644 --- a/components/mdx/Pre.tsx +++ b/components/mdx/Pre.tsx @@ -1,12 +1,6 @@ import classNames from 'classnames'; import useCopyToClipboard from 'lib/hooks/useCopyToClipboard'; -import { - DetailedHTMLProps, - HTMLAttributes, - lazy, - Suspense, - useRef, -} from 'react'; +import { DetailedHTMLProps, HTMLAttributes, lazy, useRef } from 'react'; const CopyButton = lazy(() => import('components/post/CopyButton')); @@ -34,9 +28,7 @@ const Pre = ({ ...rest }: Props) => { {...props} > {children} - - - + ); diff --git a/components/pages/ProjectCard.tsx b/components/pages/ProjectCard.tsx new file mode 100644 index 0000000..e88efc6 --- /dev/null +++ b/components/pages/ProjectCard.tsx @@ -0,0 +1,54 @@ +import classNames from 'classnames'; +import { Project } from 'pages/projects'; +import { Children, cloneElement, isValidElement } from 'react'; +import { VscGithubInverted } from 'react-icons/vsc'; + +type ProjectCardProps = { + project: Project; + icon?: React.ReactElement<{ className?: string }>; +}; + +const ProjectCard = ({ project, icon }: ProjectCardProps) => { + const Icon = Children.map(icon, (child) => { + if (!isValidElement(child)) return child; + return cloneElement(child, { + className: 'w-8 h-8', + }); + }); + + return ( + <> +
+ {Icon ? Icon : } + + +

{project.name}

+ + {project.description} + +
+
+ + ); +}; + +export default ProjectCard; diff --git a/pages/about.tsx b/pages/about.tsx index 706ac82..aa9601a 100644 --- a/pages/about.tsx +++ b/pages/about.tsx @@ -10,12 +10,11 @@ import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; import { NextPageWithLayout } from 'types'; const Loading = dynamic(() => import('components/RUA/loading/RUALoading')); +const MainLayout = dynamic(() => import('layouts/MainLayout')); const rotationY = 0.4; const rotationX = 0.2; -const MainLayout = dynamic(() => import('layouts/MainLayout')); - const About: NextPageWithLayout = () => { const [loading, setLoading] = useState(true); const [showLoading, setShowLoading] = useState(true); @@ -174,7 +173,7 @@ const About: NextPageWithLayout = () => { 'absolute top-0 left-0', 'items-center flex justify-center', 'w-full h-full transition-all duration-500', - 'bg-white', + 'bg-white dark:bg-rua-gray-900', loading ? 'opacity-1' : 'opacity-0' )} > diff --git a/pages/p/[slug].tsx b/pages/p/[slug].tsx index 31c2fdf..e87f8e9 100644 --- a/pages/p/[slug].tsx +++ b/pages/p/[slug].tsx @@ -1,15 +1,15 @@ -import { allPostsPath, readSinglePost } from 'lib/posts'; -import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'; -import { serialize } from 'next-mdx-remote/serialize'; -import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'; -import components from 'components/mdx/components'; -import data from 'data/mdxData'; import rehypePrism from '@mapbox/rehype-prism'; -import remarkGfm from 'remark-gfm'; -import rehypeSlug from 'rehype-slug'; -import dynamic from 'next/dynamic'; -import { generateToc, SingleToc } from 'lib/utils'; +import components from 'components/mdx/components'; import PostToc from 'components/post/PostToc'; +import data from 'data/mdxData'; +import { allPostsPath, readSinglePost } from 'lib/posts'; +import { generateToc, SingleToc } from 'lib/utils'; +import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'; +import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'; +import { serialize } from 'next-mdx-remote/serialize'; +import dynamic from 'next/dynamic'; +import rehypeSlug from 'rehype-slug'; +import remarkGfm from 'remark-gfm'; const Footer = dynamic(() => import('components/Footer')); const HeadBar = dynamic(() => import('components/NavBar')); diff --git a/pages/projects.tsx b/pages/projects.tsx new file mode 100644 index 0000000..3543e85 --- /dev/null +++ b/pages/projects.tsx @@ -0,0 +1,94 @@ +import classNames from 'classnames'; +import { GetStaticProps, InferGetStaticPropsType } from 'next'; +import dynamic from 'next/dynamic'; +import { ReactElement } from 'react'; +import { SiGitea } from 'react-icons/si'; + +const MainLayout = dynamic(() => import('layouts/MainLayout')); +const ProjectCard = dynamic(() => import('components/pages/ProjectCard')); + +const Projects = ({ + projects, + selfHosts, +}: InferGetStaticPropsType) => { + return ( + <> +
+
+ {/* Git projects */} +
+

Projects

+
+
+ {projects.map((item) => ( + + ))} +
+
+ +
+
+

Seft Hosts

+
+
+ {selfHosts.map((item) => ( + } key={item.id} project={item} /> + ))} +
+
+
+ + ); +}; + +export type Project = { + id: number; + name: string; + description: string; + url: string; +}; + +export const getStaticProps: GetStaticProps<{ + projects: Project[]; + selfHosts: Project[]; +}> = async () => { + const projects = [ + { + id: 0, + name: '3d-globe', + description: 'A 3d globe made by three.js.', + url: 'https://github.com/DefectingCat/3d-globe', + }, + ]; + const selfHosts = [ + { + id: 0, + name: 'Gitea', + description: 'Selfhost git.', + url: 'https://git.rua.plus/', + }, + ]; + + return { + props: { + projects, + selfHosts, + }, + }; +}; + +Projects.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default Projects;