Skip to content

Commit 761b17d

Browse files
committed
feat: init homePage
1 parent 0fd2ae9 commit 761b17d

File tree

7 files changed

+213
-10
lines changed

7 files changed

+213
-10
lines changed

next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import NextBundleAnalyzer from '@next/bundle-analyzer';
33

44
let nextConfig = {
55
images: {
6-
domains: ['innei.in'],
6+
domains: ['innei.in','images.unsplash.com','assets.aceternity.com'],
77
},
88
};
99

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

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import Image from 'next/image';
77
import { TextUpTransitionView } from '@/components/ui/transition/TextUpTransitionView';
88
import { SocialIcon } from '@/components/modules/home/SocialIcon';
99
import { cn } from '@/lib/helper';
10+
import { FocusCards } from '@/components/ui/focus-cards.tsx';
1011

1112
export default function Home() {
1213
return (
1314
<div>
1415
<Hero />
16+
<BlogCardList />
1517
</div>
1618
);
1719
}
@@ -36,7 +38,7 @@ const TwoColumnLayout = ({
3638
'relative mx-auto block size-full min-w-0 max-w-[1800px] flex-col flex-wrap items-center lg:flex lg:flex-row',
3739
className,
3840
)}
39-
style={{ padding: '0 20px' }} // 增加内边距
41+
style={{ padding: '0 20px' }}
4042
>
4143
{children.slice(0, 2).map((child, i) => (
4244
<div
@@ -58,11 +60,19 @@ const TwoColumnLayout = ({
5860
const Hero = () => {
5961
const title = {
6062
template: [
61-
{ type: 'h1', text: `Hi, I'm zw👋`, class: ' font-light text-4xl font-900' },
63+
{ type: 'h1', text: `Hi, I'm `, class: ' font-light text-4xl font-900 inline-block' },
64+
{ type: 'h1', text: `zw`, class: ' font-light text-4xl font-bold inline-block' },
65+
{
66+
type: 'h1',
67+
text: `👋`,
68+
class:
69+
' font-light text-4xl font-bold inline-block hover:scale-[1.05] cursor-pointer origin-center transition-all',
70+
},
71+
{ type: 'h1', text: ` `, class: ' h-0 w-0 scale-0' },
6272
{
6373
type: 'span',
6474
text: 'A NodeJS Full Stack ',
65-
class: 'font-light text-4xl font-900 inline-block mt-[20px]',
75+
class: 'font-light text-4xl font-900 inline-block mt-[5px]',
6676
},
6777
{
6878
type: 'code',
@@ -133,8 +143,8 @@ const Hero = () => {
133143
<span className=" opacity-70"> {description}</span>
134144
</motion.div>
135145

136-
<ul className="center mx-[60px] mt-8 flex flex-wrap gap-6 lg:mx-auto lg:mt-14 lg:justify-start lg:gap-4 lg:ml-24">
137-
{Object.entries(socialIds).map(([type, id]) => (
146+
<ul className="center mx-[60px] mt-8 flex flex-wrap gap-6 lg:mx-auto lg:mt-24 lg:justify-start lg:gap-4 lg:ml-24">
147+
{Object.entries(socialIds).map(([type, id], index) => (
138148
<motion.li
139149
key={type}
140150
initial={{ y: 50, opacity: 0 }}
@@ -143,7 +153,7 @@ const Hero = () => {
143153
type: 'spring',
144154
damping: 10,
145155
stiffness: 100,
146-
delay: titleAnimateD / 1000,
156+
delay: titleAnimateD / 1000 + index * 0.08,
147157
}}
148158
className="inline-block"
149159
>
@@ -204,3 +214,41 @@ const Quote = () => {
204214
</motion.div>
205215
);
206216
};
217+
218+
const BlogCardList = () => {
219+
const cards = [
220+
{
221+
title: 'Forest Adventure',
222+
src: 'https://images.unsplash.com/photo-1518710843675-2540dd79065c?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
223+
},
224+
{
225+
title: 'Valley of life',
226+
src: 'https://images.unsplash.com/photo-1600271772470-bd22a42787b3?q=80&w=3072&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
227+
},
228+
{
229+
title: 'Sala behta hi jayega',
230+
src: 'https://images.unsplash.com/photo-1505142468610-359e7d316be0?q=80&w=3070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
231+
},
232+
{
233+
title: 'Camping is for pros',
234+
src: 'https://images.unsplash.com/photo-1486915309851-b0cc1f8a0084?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
235+
},
236+
{
237+
title: 'The road not taken',
238+
src: 'https://images.unsplash.com/photo-1507041957456-9c397ce39c97?q=80&w=3456&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
239+
},
240+
{
241+
title: 'The First Rule',
242+
src: 'https://assets.aceternity.com/the-first-rule.png',
243+
},
244+
];
245+
246+
return (
247+
<div className=" w-screen mt-10 md:mt-16 flex flex-col gap-y-8 px-8">
248+
<span className="text-2xl font-medium leading-loose ml-4 font-mono hidden md:block">
249+
最近文章
250+
</span>
251+
<FocusCards cards={cards} />
252+
</div>
253+
);
254+
};

src/components/layout/Footer/Footer.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
1+
import Link from 'next/link';
2+
13
import ThemeSwitcher from '@/components/ui/ThemeSwitcher';
24

35
const Footer = () => {
46
return (
57
<footer
68
data-hide-print
7-
className="relative z-[1] h-40 mt-32 border-t border-x-uk-separator-opaque-light py-6 text-base-content/80 dark:border-white/10"
9+
className="relative z-[1] h-28 mt-32 pb-6 border-t border-x-uk-separator-opaque-light py-6 text-base-content/80 dark:border-white/10"
810
>
911
<div className="px-4 sm:px-8 h-full">
10-
<div className="relative mx-auto max-w-7xl lg:px-8 h-full">
11-
<div className="mt-6 block text-center md:absolute md:bottom-0 md:right-0 md:mt-0">
12+
<div className="relative mx-auto max-w-7xl lg:px-8 h-full flex flex-row items-center justify-around">
13+
<div className=" flex items-center gap-x-4 font-mono">
14+
<span className="">
15+
<Link href={'/'}>
16+
<span className=" relative before:content-[''] before:absolute before:bottom-[-2px] before:w-[0px] hover:before:w-[100%] before:h-[1px] before:bg-[var(--accent-color)] before:transition-all before:duration-300">
17+
关于我
18+
</span>
19+
</Link>
20+
</span>
21+
<span className="">
22+
<Link href={'/'}>
23+
<span className=" relative before:content-[''] before:absolute before:bottom-[-2px] before:w-[0px] hover:before:w-[100%] before:h-[1px] before:bg-[var(--accent-color)] before:transition-all before:duration-300">
24+
此项目
25+
</span>
26+
</Link>
27+
</span>
28+
</div>
29+
<div className=" flex items-center text-center md:absolute md:bottom-0 md:right-0">
1230
<ThemeSwitcher></ThemeSwitcher>
1331
</div>
1432
</div>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
3+
type BlogPostCardProps = {
4+
title: string;
5+
date: string;
6+
readingTime: string;
7+
views: number;
8+
imageUrl: string;
9+
};
10+
11+
const BlogPostCard: React.FC<BlogPostCardProps> = ({
12+
title,
13+
date,
14+
readingTime,
15+
views,
16+
imageUrl,
17+
}) => {
18+
return (
19+
<div className="relative group w-full max-w-md p-4 rounded-2xl overflow-hidden text-white shadow-lg">
20+
{/* 背景图像,只有在 hover 时模糊 */}
21+
<div
22+
className="absolute inset-0 w-full h-full bg-cover bg-center group-hover:blur-sm transition duration-300 ease-in-out"
23+
style={{ backgroundImage: `url(${imageUrl})` }}
24+
/>
25+
26+
{/* 半透明覆盖层 */}
27+
<div className="absolute inset-0 bg-black bg-opacity-30 group-hover:bg-opacity-50 transition duration-300 ease-in-out" />
28+
29+
{/* 内容层 */}
30+
<div className="relative z-10 flex flex-col justify-between h-full p-6">
31+
{/* 顶部头像 */}
32+
<div className="flex justify-start items-center mb-4">
33+
<img src="/path-to-avatar.png" alt="avatar" className="h-10 w-10 rounded-full" />
34+
</div>
35+
36+
{/* 中间主要标题 */}
37+
<div className="flex-1 text-left">
38+
<h2 className="text-3xl font-bold mb-4">{title}</h2>
39+
</div>
40+
41+
{/* 底部信息 */}
42+
<div className="text-sm mt-4 flex justify-between items-center">
43+
<div className="flex items-center">
44+
<span className="mr-2">📅 {date}</span>
45+
<span>🖊 随笔</span>
46+
</div>
47+
<div className="flex items-center">
48+
<span className="mr-4">👁 {views}</span>
49+
<span>{readingTime}</span>
50+
</div>
51+
</div>
52+
</div>
53+
</div>
54+
);
55+
};
56+
57+
export default BlogPostCard;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './BlogPostCard';
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use client';
2+
3+
import Image from 'next/image';
4+
import React, { useState } from 'react';
5+
6+
import { cn } from '@/lib/helper';
7+
8+
export const Card = React.memo(
9+
({
10+
card,
11+
index,
12+
hovered,
13+
setHovered,
14+
}: {
15+
card: any;
16+
index: number;
17+
hovered: number | null;
18+
setHovered: React.Dispatch<React.SetStateAction<number | null>>;
19+
}) => (
20+
<div
21+
onMouseEnter={() => setHovered(index)}
22+
onMouseLeave={() => setHovered(null)}
23+
className={cn(
24+
'rounded-lg relative bg-gray-100 dark:bg-neutral-900 overflow-hidden h-60 md:h-96 w-full transition-all duration-300 ease-out cursor-pointer',
25+
hovered !== null && hovered !== index && 'blur-sm scale-[0.98]',
26+
)}
27+
>
28+
<Image src={card.src} alt={card.title} fill className="object-cover absolute inset-0" />
29+
<div
30+
className={cn(
31+
'absolute inset-0 bg-black/50 flex flex-col justify-end py-8 px-4 transition-opacity duration-300', // 修改为 flex-col
32+
hovered === index ? 'opacity-100' : 'opacity-60',
33+
)}
34+
>
35+
{/* 标题 */}
36+
<div className="text-xl md:text-2xl font-medium bg-clip-text text-transparent bg-gradient-to-b from-neutral-50 to-neutral-200 mb-2">
37+
{card.title}
38+
</div>
39+
{/* 日期 */}
40+
<div className="text-sm text-neutral-300 flex flex-nowrap gap-x-4">
41+
<div className=" flex items-center justify-start gap-x-1">
42+
<i className=" i-material-symbols-calendar-clock-outline-sharp text-lg"></i>
43+
<span>2024/06/24</span>
44+
</div>
45+
<div className=" flex items-center justify-start gap-x-1">
46+
<i className=" i-material-symbols-edit text-lg"></i>
47+
<span>随笔</span>
48+
</div>
49+
</div>
50+
</div>
51+
</div>
52+
),
53+
);
54+
55+
Card.displayName = 'Card';
56+
57+
type Card = {
58+
title: string;
59+
src: string;
60+
};
61+
62+
export function FocusCards({ cards }: { cards: Card[] }) {
63+
const [hovered, setHovered] = useState<number | null>(null);
64+
65+
return (
66+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-10 max-w-[7xl] mx-auto md:px-8 w-full">
67+
{cards.map((card, index) => (
68+
<Card
69+
key={card.title}
70+
card={card}
71+
index={index}
72+
hovered={hovered}
73+
setHovered={setHovered}
74+
/>
75+
))}
76+
</div>
77+
);
78+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './FocusCards';

0 commit comments

Comments
 (0)