Skip to content

Commit 8fde7cd

Browse files
committed
feat: project page
1 parent 3e5708a commit 8fde7cd

File tree

7 files changed

+138
-2
lines changed

7 files changed

+138
-2
lines changed

config/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export { seo } from './seo';
22
export { friendsList } from './friends';
3+
export { projectList } from './projects';
34

45
export type { FriendModel } from './friends';
6+
export type { ProjectModel } from './projects';

config/projects.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export const projectList: ProjectModel[] = [
2+
{ id: '1', name: 'blog', url: 'https://github.com/coderz-w/blog', desc: '我的个人博客' },
3+
{
4+
id: '2',
5+
name: 'online-edit-web',
6+
url: 'https://github.com/xun082/online-edit-web',
7+
desc: '基于webContainer的代码编辑器',
8+
},
9+
{ id: '6', name: 'canvas', url: 'https://github.com/coderz-w/canvas', desc: 'canvas画板' },
10+
];
11+
12+
export interface ProjectModel {
13+
id: string | number;
14+
name: string;
15+
url: string;
16+
avatar?: string;
17+
desc: string;
18+
}

src/app/(app)/projects/layout.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { Metadata } from 'next';
2+
import type { PropsWithChildren } from 'react';
3+
4+
import { NormalContainer } from '@/components/layout/container/Normal';
5+
6+
export const metadata: Metadata = {
7+
title: '看看我在做啥',
8+
};
9+
10+
export default async function (props: PropsWithChildren) {
11+
return <NormalContainer>{props.children}</NormalContainer>;
12+
}

src/app/(app)/projects/page.tsx

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
'use client';
2+
3+
import Link from 'next/link';
4+
import Image from 'next/image';
5+
6+
import { GitHubBrandIcon } from '@/components/icons/platform/GitHubBrandIcon';
7+
import { cn } from '@/lib/helper';
8+
import { ProjectModel, projectList } from '~/index';
9+
10+
export default function Projects() {
11+
return (
12+
<div>
13+
<header className="prose prose-p:my-2 font-mono">
14+
<h1 className=" flex items-center">
15+
项目
16+
<a
17+
href={`https://github.com/coderz-w`}
18+
className="ml-2 inline-flex !text-inherit"
19+
target="_blank"
20+
aria-label="view on GitHub"
21+
rel="noopener noreferrer"
22+
>
23+
<GitHubBrandIcon />
24+
</a>
25+
</h1>
26+
</header>
27+
28+
<main className="mt-10 flex w-full flex-col">
29+
<ProjectCardList data={projectList} />
30+
</main>
31+
</div>
32+
);
33+
}
34+
35+
const ProjectCardList = ({ data }: { data: ProjectModel[] }) => (
36+
<div className="grid min-w-0 grid-cols-2 gap-6 lg:grid-cols-3">
37+
{data.map((projectModel) => {
38+
return <ProjectCard project={projectModel} />;
39+
})}
40+
</div>
41+
);
42+
const ProjectCard = ({ project }: { project: ProjectModel }) => {
43+
return (
44+
<Link
45+
href={project.url}
46+
key={project.id}
47+
className="group flex shrink-0 grid-cols-[60px_2fr] flex-col items-center gap-4 md:grid"
48+
>
49+
<ProjectIcon
50+
className="size-16 group-hover:-translate-y-2 group-hover:shadow-out-sm md:size-auto"
51+
avatar={project.avatar}
52+
name={project.name}
53+
/>
54+
<span className="flex shrink-0 grow flex-col gap-2 text-left">
55+
<h4 className="m-0 text-balance p-0 text-center font-medium md:text-left">
56+
{project.name}
57+
</h4>
58+
<span className="line-clamp-5 text-balance text-center text-sm md:line-clamp-4 md:text-left lg:line-clamp-2">
59+
{project.desc}
60+
</span>
61+
</span>
62+
</Link>
63+
);
64+
};
65+
66+
const ProjectIcon = (props: { avatar?: string; name?: string; className?: string }) => {
67+
const { avatar, name, className } = props;
68+
69+
return (
70+
<div
71+
className={cn(
72+
'project-icon flex shrink-0 grow items-center justify-center',
73+
avatar
74+
? 'ring-2 ring-slate-200 dark:ring-neutral-800'
75+
: 'bg-slate-300 text-white dark:bg-neutral-800 text-3xl',
76+
'mask mask-squircle aspect-square transition-all duration-300',
77+
className,
78+
)}
79+
>
80+
{avatar ? (
81+
<Image
82+
src={avatar}
83+
height={64}
84+
width={64}
85+
alt={`Avatar of ${name}`}
86+
className=" rounded-xl duration-300 transition-all aspect-square"
87+
/>
88+
) : (
89+
<> {name?.charAt(0).toUpperCase() || ''}</>
90+
)}
91+
</div>
92+
);
93+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export function GitHubBrandIcon(props: React.SVGAttributes<SVGElement>) {
2+
return (
3+
<svg width="1em" height="1em" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg" {...props}>
4+
<path
5+
fillRule="evenodd"
6+
clipRule="evenodd"
7+
d="M7.5 0C3.35625 0 0 3.35625 0 7.5C0 10.8187 2.14687 13.6219 5.12812 14.6156C5.50312 14.6813 5.64375 14.4563 5.64375 14.2594C5.64375 14.0813 5.63438 13.4906 5.63438 12.8625C3.75 13.2094 3.2625 12.4031 3.1125 11.9812C3.02812 11.7656 2.6625 11.1 2.34375 10.9219C2.08125 10.7812 1.70625 10.4344 2.33438 10.425C2.925 10.4156 3.34688 10.9687 3.4875 11.1937C4.1625 12.3281 5.24063 12.0094 5.67188 11.8125C5.7375 11.325 5.93437 10.9969 6.15 10.8094C4.48125 10.6219 2.7375 9.975 2.7375 7.10625C2.7375 6.29062 3.02813 5.61562 3.50625 5.09062C3.43125 4.90312 3.16875 4.13437 3.58125 3.10312C3.58125 3.10312 4.20938 2.90625 5.64375 3.87188C6.24375 3.70313 6.88125 3.61875 7.51875 3.61875C8.15625 3.61875 8.79375 3.70313 9.39375 3.87188C10.8281 2.89688 11.4563 3.10312 11.4563 3.10312C11.8688 4.13437 11.6063 4.90312 11.5313 5.09062C12.0094 5.61562 12.3 6.28125 12.3 7.10625C12.3 9.98437 10.5469 10.6219 8.87813 10.8094C9.15 11.0437 9.38438 11.4938 9.38438 12.1969C9.38438 13.2 9.375 14.0063 9.375 14.2594C9.375 14.4563 9.51563 14.6906 9.89063 14.6156C12.8531 13.6219 15 10.8094 15 7.5C15 3.35625 11.6438 0 7.5 0Z"
8+
fill="currentColor"
9+
/>
10+
</svg>
11+
);
12+
}

src/components/modules/toc/TocTree.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function useActiveId($headings: HTMLHeadingElement[]) {
3131
entries.forEach((entry) => {
3232
if (entry.isIntersecting) {
3333
startTransition(() => {
34-
setActiveId(entry.target.id);
34+
if (activeId != entry.target.id) setActiveId(entry.target.id);
3535
});
3636
}
3737
});

src/styles/layer.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@
122122
fill: transparent;
123123
}
124124
}
125-
126125

127126
.animation-wave {
128127
animation: wave 2s infinite;

0 commit comments

Comments
 (0)