From 413b77691b21824342660ac7d744a61834464036 Mon Sep 17 00:00:00 2001 From: Kuizuo Date: Sat, 15 Jun 2024 09:31:30 +0800 Subject: [PATCH] refactor: FeatureSection --- data/features.tsx | 25 ++++---- package.json | 1 + pnpm-lock.yaml | 57 +++++++++++++++++++ .../landing/FeaturesSection/Github.tsx | 28 ++++++--- .../landing/FeaturesSection/index.tsx | 42 ++++++-------- src/components/magicui/bento-grid.tsx | 47 +++++++++++++++ 6 files changed, 156 insertions(+), 44 deletions(-) create mode 100644 src/components/magicui/bento-grid.tsx diff --git a/data/features.tsx b/data/features.tsx index 2da1969b..e96c0ffb 100644 --- a/data/features.tsx +++ b/data/features.tsx @@ -1,12 +1,14 @@ -import WebDeveloperSvg from '@site/static/svg/undraw_web_developer.svg' +import Translate, { translate } from '@docusaurus/Translate' +import { Icon } from '@iconify/react/dist/iconify.js' import OpenSourceSvg from '@site/static/svg/undraw_open_source.svg' import SpiderSvg from '@site/static/svg/undraw_spider.svg' -import Translate, { translate } from '@docusaurus/Translate' +import WebDeveloperSvg from '@site/static/svg/undraw_web_developer.svg' export type FeatureItem = { - title: string - text: JSX.Element - Svg: React.ComponentType> + title: string | React.ReactNode + description: string | React.ReactNode + header: React.ReactNode + icon?: React.ReactNode } const FEATURES: FeatureItem[] = [ @@ -15,36 +17,37 @@ const FEATURES: FeatureItem[] = [ id: 'homepage.feature.developer', message: 'TypeScript 全栈工程师', }), - text: ( + description: ( 作为一名 TypeScript 全栈工程师,秉着能用 TS 绝不用 JS 的原则,为项目提供类型安全的保障,提高代码质量和开发效率。 ), - Svg: WebDeveloperSvg, + header: , + icon: , }, { title: translate({ id: 'homepage.feature.spider', message: '会点逆向 & 爬虫', }), - text: ( + description: ( 作为一名曾学习与实践逆向工程两年半的开发者,对于逆向工程有着浓厚的兴趣,同时造就了超凡的阅读代码能力。没有看不懂的代码,只有不想看的代码。 ), - Svg: SpiderSvg, + header: , }, { title: translate({ id: 'homepage.feature.enthusiast', message: '开源爱好者', }), - text: ( + description: ( 作为一名开源爱好者,积极参与开源社区,为开源项目贡献代码,希望有生之年能够构建出一个知名的开源项目。 ), - Svg: OpenSourceSvg, + header: , }, ] diff --git a/package.json b/package.json index f07fe55e..f84a9d27 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "raw-loader": "^4.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-github-calendar": "^4.1.5", "react-icon-cloud": "^4.1.4", "react-popper": "^2.3.0", "tailwind-merge": "^2.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 497223aa..2fedf327 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,6 +71,9 @@ importers: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + react-github-calendar: + specifier: ^4.1.5 + version: 4.1.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-icon-cloud: specifier: ^4.1.4 version: 4.1.4(react@18.2.0) @@ -1158,6 +1161,7 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -1165,6 +1169,7 @@ packages: '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead '@iconify/react@4.1.1': resolution: {integrity: sha512-jed14EjvKjee8mc0eoscGxlg7mSQRkwQG3iX3cPBCO7UlOjz0DtlvTqxqEcHUJGh+z1VJ31Yhu5B9PxfO0zbdg==} @@ -1434,6 +1439,9 @@ packages: '@types/bonjour@3.5.10': resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} + '@types/chroma-js@2.4.4': + resolution: {integrity: sha512-/DTccpHTaKomqussrn+ciEvfW4k6NAHzNzs/sts1TCqg333qNxOhy8TNIoQCmbGG3Tl8KdEhkGAssb1n3mTXiQ==} + '@types/connect-history-api-fallback@1.5.1': resolution: {integrity: sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw==} @@ -1994,6 +2002,9 @@ packages: chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chroma-js@2.4.2: + resolution: {integrity: sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==} + chrome-trace-event@1.0.3: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} engines: {node: '>=6.0'} @@ -2291,6 +2302,9 @@ packages: csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -4516,6 +4530,12 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true + react-activity-calendar@2.2.10: + resolution: {integrity: sha512-6UsPmw6jD5TM5DHAVCIKkOhqdcJ1reOrFsMd3pDnQ5Yo8WfkFoDLjYQRYUkH6BWhishVpZ3JTn39Tf+3JyVY6w==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + react-dev-utils@12.0.1: resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} engines: {node: '>=14'} @@ -4531,12 +4551,23 @@ packages: peerDependencies: react: ^18.2.0 + react-error-boundary@4.0.13: + resolution: {integrity: sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==} + peerDependencies: + react: '>=16.13.1' + react-error-overlay@6.0.11: resolution: {integrity: sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==} react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + react-github-calendar@4.1.5: + resolution: {integrity: sha512-l3Uzt2TnDdFGeKSpqpbX1rwIYydQLmVk4kjS6lpBhtbKAG1ejVRLbqM1TJhLgRIzORlouzGz94sis3trCiTi7A==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + react-helmet-async@1.3.0: resolution: {integrity: sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==} peerDependencies: @@ -7711,6 +7742,8 @@ snapshots: dependencies: '@types/node': 20.5.9 + '@types/chroma-js@2.4.4': {} + '@types/connect-history-api-fallback@1.5.1': dependencies: '@types/express-serve-static-core': 4.17.36 @@ -8370,6 +8403,8 @@ snapshots: chownr@1.1.4: {} + chroma-js@2.4.2: {} + chrome-trace-event@1.0.3: {} ci-info@3.8.0: {} @@ -8675,6 +8710,8 @@ snapshots: csstype@3.1.2: {} + date-fns@3.6.0: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -11292,6 +11329,14 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 + react-activity-calendar@2.2.10(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@types/chroma-js': 2.4.4 + chroma-js: 2.4.2 + date-fns: 3.6.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-dev-utils@12.0.1(eslint@8.57.0)(typescript@5.3.3)(webpack@5.88.2): dependencies: '@babel/code-frame': 7.23.5 @@ -11332,10 +11377,22 @@ snapshots: react: 18.2.0 scheduler: 0.23.0 + react-error-boundary@4.0.13(react@18.2.0): + dependencies: + '@babel/runtime': 7.24.6 + react: 18.2.0 + react-error-overlay@6.0.11: {} react-fast-compare@3.2.2: {} + react-github-calendar@4.1.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + react: 18.2.0 + react-activity-calendar: 2.2.10(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + react-error-boundary: 4.0.13(react@18.2.0) + react-helmet-async@1.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@babel/runtime': 7.24.6 diff --git a/src/components/landing/FeaturesSection/Github.tsx b/src/components/landing/FeaturesSection/Github.tsx index 114f3fe2..9db1bad2 100644 --- a/src/components/landing/FeaturesSection/Github.tsx +++ b/src/components/landing/FeaturesSection/Github.tsx @@ -1,19 +1,33 @@ import Translate from '@docusaurus/Translate' +import GitHubCalendar from 'react-github-calendar' +import { useColorMode } from '@docusaurus/theme-common' import { Icon } from '@iconify/react' -export default function Skill({ className }: { className?: string }) { +interface GithubProps { + className?: string +} + +export default function Github({ className }: GithubProps) { + const { isDarkTheme } = useColorMode() + + const githubStatsUrl = (type: 'overview' | 'languages') => + `https://raw.githubusercontent.com/kuizuo/github-stats/master/generated/${type}.svg#gh-${ + isDarkTheme ? 'dark' : 'light' + }-mode-only` + return (
-

+

Github

-
- kuizuo's Github chart +
+
+ GitHub Overview Stats + GitHub Languages Stats +
+
) diff --git a/src/components/landing/FeaturesSection/index.tsx b/src/components/landing/FeaturesSection/index.tsx index 14245284..b21e4963 100644 --- a/src/components/landing/FeaturesSection/index.tsx +++ b/src/components/landing/FeaturesSection/index.tsx @@ -1,39 +1,29 @@ import Translate from '@docusaurus/Translate' -import features, { type FeatureItem } from '@site/data/features' -import { cn } from '@site/src/lib/utils' +import features from '@site/data/features' +import { BentoGrid, BentoGridItem } from '../../magicui/bento-grid' import { Section } from '../Section' import Github from './Github' import Skill from './Skill' -function Feature({ title, Svg, text }: FeatureItem) { - return ( -
-
- -
-
-

{title}

-

{text}

-
-
- ) -} - export default function FeaturesSection() { return (
个人特点} icon={'ri:map-pin-user-line'}> -
- {features.map((props, idx) => ( - + + {features.map((item, i) => ( + ))} -
-
+ + +
- +
) diff --git a/src/components/magicui/bento-grid.tsx b/src/components/magicui/bento-grid.tsx new file mode 100644 index 00000000..bad17146 --- /dev/null +++ b/src/components/magicui/bento-grid.tsx @@ -0,0 +1,47 @@ +import { cn } from '@site/src/lib/utils' + +export const BentoGrid = ({ + className, + children, +}: { + className?: string + children?: React.ReactNode +}) => { + return ( +
+ {children} +
+ ) +} + +export const BentoGridItem = ({ + className, + title, + description, + header, + icon, +}: { + className?: string + title?: string | React.ReactNode + description?: string | React.ReactNode + header?: React.ReactNode + icon?: React.ReactNode +}) => { + return ( +
+ {header} +
+
+ {icon} +
{title}
+
+
{description}
+
+
+ ) +}