├── .eslintrc.json ├── README.md ├── public ├── avatar.jpg ├── iconfont.ttf ├── posts │ ├── i-made-a-navigation-website.md │ ├── creative-commons.md │ ├── flowchart-1.md │ ├── state-as-snapshot.md │ ├── git-2.md │ ├── component-composition.md │ ├── python-lp.md │ ├── check-input-is-integer.md │ ├── react-event-this.md │ ├── ssh-1.md │ ├── linux-fundamental-1.md │ ├── markdown-syntax.md │ ├── use-image-as-background.md │ ├── event-js.md │ ├── tkinter-cheatsheet.md │ ├── matplotlib-1.md │ ├── dsa-in-python-recursion.md │ ├── git-1.md │ ├── matplotlib-2.md │ ├── linux-fundamental-2.md │ ├── tiny-compiler.md │ └── how-to-ask-question.md └── favicon.svg ├── styles ├── Divider.module.css ├── Content.module.css ├── Markdown.module.css ├── Wrapper.module.css ├── Blog.module.css ├── util.module.css ├── Cd.module.css ├── Footer.module.css ├── Post.module.css ├── Avatar.module.css ├── Nav.module.css ├── markdown.css ├── Project.module.css └── globals.css ├── components ├── Divider.js ├── Wrapper.js ├── Cd.js ├── Blog │ ├── Post.js │ └── Content.js ├── Project │ └── Item.js ├── Footer.js ├── Layout.js ├── Home │ ├── Avatar.js │ └── Content.js └── NavBar.js ├── pages ├── api │ └── hello.js ├── _app.js ├── _document.js ├── index.js ├── blog.js ├── blog │ └── [id].js └── project.js ├── next.config.js ├── .gitignore ├── package.json ├── LICENSE └── utils └── postTools.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My Portfolio Website 2 | 3 | https://kelvinqiu.tech 4 | -------------------------------------------------------------------------------- /public/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KelvinQiu802/portfolio/HEAD/public/avatar.jpg -------------------------------------------------------------------------------- /public/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KelvinQiu802/portfolio/HEAD/public/iconfont.ttf -------------------------------------------------------------------------------- /styles/Divider.module.css: -------------------------------------------------------------------------------- 1 | .divider { 2 | width: 100px; 3 | height: 1px; 4 | background-color: var(--surface1); 5 | margin: 23px auto; 6 | } 7 | -------------------------------------------------------------------------------- /components/Divider.js: -------------------------------------------------------------------------------- 1 | import styles from '../styles/Divider.module.css'; 2 | 3 | const Divider = () => { 4 | return
; 5 | }; 6 | 7 | export default Divider; 8 | -------------------------------------------------------------------------------- /pages/api/hello.js: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | 3 | export default function handler(req, res) { 4 | res.status(200).json({ name: 'John Doe' }) 5 | } 6 | -------------------------------------------------------------------------------- /styles/Content.module.css: -------------------------------------------------------------------------------- 1 | .content { 2 | line-height: 29px; 3 | margin-top: 30px; 4 | } 5 | 6 | @media screen and (max-width: 600px) { 7 | .content { 8 | margin-top: 12px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /components/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styles from '../styles/Wrapper.module.css'; 2 | 3 | const Wrapper = ({ children }) => { 4 | return
{children}
; 5 | }; 6 | 7 | export default Wrapper; 8 | -------------------------------------------------------------------------------- /styles/Markdown.module.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-size: 30px; 3 | font-weight: 500; 4 | color: var(--element3); 5 | } 6 | 7 | .date { 8 | font-size: 15px; 9 | color: var(--element4); 10 | transition: 0.3s; 11 | margin: 15px 0; 12 | text-align: end; 13 | } 14 | -------------------------------------------------------------------------------- /styles/Wrapper.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | max-width: 820px; 3 | margin: 0 auto; 4 | margin-top: 20px; 5 | padding: 0 40px; 6 | } 7 | 8 | @media screen and (max-width: 600px) { 9 | .wrapper { 10 | margin-top: 5px; 11 | padding: 0 25px; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | swcMinify: true, 5 | images: { 6 | loader: 'akamai', 7 | path: '', 8 | }, 9 | trailingSlash: true, 10 | }; 11 | module.exports = nextConfig; 12 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import Layout from '../components/Layout'; 2 | import '../styles/globals.css'; 3 | import '../styles/markdown.css'; 4 | 5 | function MyApp({ Component, pageProps }) { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | export default MyApp; 14 | -------------------------------------------------------------------------------- /styles/Blog.module.css: -------------------------------------------------------------------------------- 1 | .year { 2 | font-size: 30px; 3 | color: var(--element4); 4 | text-align: start; 5 | margin-bottom: 15px; 6 | margin-right: 40px; 7 | } 8 | 9 | @media screen and (max-width: 600px) { 10 | .year { 11 | font-size: 25px; 12 | margin-right: 20px; 13 | margin-bottom: 5px; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /components/Cd.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | import styles from '../styles/Cd.module.css'; 3 | 4 | const Cd = () => { 5 | return ( 6 |
7 | 8 | cd.. 9 | 10 |
11 | ); 12 | }; 13 | 14 | export default Cd; 15 | -------------------------------------------------------------------------------- /styles/util.module.css: -------------------------------------------------------------------------------- 1 | .plain { 2 | font-size: 16px; 3 | color: var(--element1); 4 | } 5 | 6 | .stress { 7 | font-size: 16px; 8 | color: var(--element3); 9 | } 10 | 11 | .textLink { 12 | font-size: 16px; 13 | color: var(--element3); 14 | text-decoration: underline; 15 | text-decoration-color: var(--element2); 16 | } 17 | -------------------------------------------------------------------------------- /styles/Cd.module.css: -------------------------------------------------------------------------------- 1 | .cd { 2 | margin-top: 20px; 3 | margin-bottom: 40px; 4 | } 5 | 6 | .link { 7 | font-size: 16px; 8 | color: var(--element2); 9 | text-decoration: underline; 10 | text-decoration-color: var(--element2); 11 | } 12 | 13 | .link:hover { 14 | color: var(--element3); 15 | text-decoration-color: var(--element3); 16 | } 17 | -------------------------------------------------------------------------------- /styles/Footer.module.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | text-align: end; 3 | margin: 60px 0; 4 | color: var(--element8); 5 | font-size: 14px; 6 | } 7 | 8 | .cc { 9 | margin-bottom: 2px; 10 | } 11 | 12 | .cc a { 13 | text-decoration: underline; 14 | text-decoration-color: var(--element8); 15 | } 16 | 17 | @media screen and (max-width: 600px) { 18 | .footer { 19 | text-align: center; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /styles/Post.module.css: -------------------------------------------------------------------------------- 1 | .post { 2 | cursor: pointer; 3 | margin-bottom: 35px; 4 | } 5 | 6 | .title { 7 | font-size: 16px; 8 | color: var(--element1); 9 | transition: 0.3s; 10 | } 11 | 12 | .date { 13 | font-size: 14px; 14 | color: var(--element4); 15 | transition: 0.3s; 16 | } 17 | 18 | .post:hover .title { 19 | color: var(--element3); 20 | } 21 | 22 | .post:hover .date { 23 | color: var(--element5); 24 | } 25 | -------------------------------------------------------------------------------- /components/Blog/Post.js: -------------------------------------------------------------------------------- 1 | import styles from '../../styles/Post.module.css'; 2 | import Link from 'next/link'; 3 | 4 | const Post = ({ title, date, id }) => { 5 | return ( 6 | 7 |
8 |

{title}

9 |

{date}

10 |
11 | 12 | ); 13 | }; 14 | 15 | export default Post; 16 | -------------------------------------------------------------------------------- /components/Project/Item.js: -------------------------------------------------------------------------------- 1 | import styles from '../../styles/Project.module.css'; 2 | 3 | const Item = ({ name, description, repo, children }) => { 4 | return ( 5 | 6 |
7 | {children} 8 |
9 |

{name}

10 |

{description}

11 |
12 |
13 |
14 | ); 15 | }; 16 | 17 | export default Item; 18 | -------------------------------------------------------------------------------- /pages/_document.js: -------------------------------------------------------------------------------- 1 | import { Head, Html, Main, NextScript } from 'next/document'; 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | import Avatar from '../components/Home/Avatar'; 3 | import Wrapper from '../components/Wrapper'; 4 | import Content from '../components/Home/Content'; 5 | import Footer from '../components/Footer'; 6 | 7 | const Home = () => { 8 | return ( 9 |
10 | 11 | Kelvin Qiu 12 | 13 | 14 | 15 | 16 |
17 | 18 |
19 | ); 20 | }; 21 | 22 | export default Home; 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | pnpm-lock.yaml 28 | 29 | 30 | # local env files 31 | .env*.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | next-env.d.ts 39 | -------------------------------------------------------------------------------- /components/Footer.js: -------------------------------------------------------------------------------- 1 | import styles from '../styles/Footer.module.css'; 2 | 3 | const Footer = () => { 4 | return ( 5 |
6 |

7 | 12 | CC BY-NC-SA 4.0 13 | {' '} 14 | © Kelvin Qiu 15 |

16 | 17 | 京ICP备2022001803号 18 | 19 |
20 | ); 21 | }; 22 | 23 | export default Footer; 24 | -------------------------------------------------------------------------------- /components/Blog/Content.js: -------------------------------------------------------------------------------- 1 | import Wrapper from '../Wrapper'; 2 | import Post from './Post'; 3 | 4 | const FIRST_YEAR = 2022; 5 | function getYears() { 6 | const date = new Date(); 7 | let currentYear = date.getFullYear(); 8 | const allYears = []; 9 | while (currentYear >= FIRST_YEAR) { 10 | allYears.push(currentYear); 11 | currentYear--; 12 | } 13 | return allYears; 14 | } 15 | 16 | const content = ({ posts }) => { 17 | return ( 18 | 19 | {posts.map((post) => ( 20 | 21 | ))} 22 | 23 | ); 24 | }; 25 | 26 | export default content; 27 | -------------------------------------------------------------------------------- /public/posts/i-made-a-navigation-website.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 我肝出了一个方便实用的导航网站! 3 | date: 2022-01-17 4 | tags: [前端,导航,网站] 5 | cover: "https://imgbed.codingkelvin.fun/uPic/008dMV7uly1gyh4m4bkh7j30h107yjsh.jpeg" 6 | top_img: false 7 | categories: [Web开发] 8 | --- 9 | 10 | ## [传送门点我!](https://nav.codingkelvin.fun) 11 | 12 | >**为什么会有这个网站?** 13 | > 14 | >😓 **学校网站记不住** 15 | > 16 | >😫 **实用工具没地儿找** 17 | > 18 | >😣 **学习资源选择恐惧症** 19 | 20 | --- 21 | 22 | ### 个人能力有限,欢迎大家投稿 23 | 24 | - 导航内设计超多板块,需要大家共同维护,网站内点击**“投稿”**将自己喜欢的网站挂上导航。 25 | 26 | [![](https://imgbed.codingkelvin.fun/uPic/008i3skNly1gyh3yj5gykj31jk06wgm5.jpg)](https://docs.qq.com/form/page/DR3F1TmFIbERSbWdK?_w_tencentdocx_form=1#/fill) 27 | 28 | -------------------------------------------------------------------------------- /pages/blog.js: -------------------------------------------------------------------------------- 1 | import Content from '../components/Blog/Content'; 2 | import Head from 'next/head'; 3 | import Footer from '../components/Footer'; 4 | import Wrapper from '../components/Wrapper'; 5 | import { getSortedPostData } from '../utils/postTools'; 6 | 7 | const blog = ({ posts }) => { 8 | return ( 9 | 10 | 11 | Kelvin's Blog 12 | 13 | 14 |