Skip to content

Commit e941011

Browse files
committed
Refactor layout and styling across various components for improved consistency and responsiveness. Update Tailwind configuration to include new animations and enhance global styles. Adjust About, Home, and Post pages for better structure and visual appeal.
1 parent 18d2d3c commit e941011

18 files changed

Lines changed: 515 additions & 304 deletions

File tree

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

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,31 @@ const educations = [
5555

5656
function AboutPage() {
5757
return (
58-
<main className={cn('px-6')}>
59-
<section className={cn('flex flex-col items-center py-12')}>
60-
<h1 className={cn('mb-1 text-base sm:text-3xl')}>
61-
안녕하세요!{' '}
62-
<span className={cn('font-bold')}>Software Engineer 신원세</span>
63-
입니다.
58+
<main className={cn('flex w-full flex-col items-center py-12')}>
59+
<section
60+
className={cn(
61+
'mb-16 flex w-full max-w-3xl flex-col items-center gap-4 text-center',
62+
)}
63+
>
64+
<h1
65+
className={cn(
66+
'text-3xl font-bold tracking-tight sm:text-5xl',
67+
'bg-gradient-to-br from-foreground to-foreground/70 bg-clip-text text-transparent',
68+
)}
69+
>
70+
안녕하세요!
6471
</h1>
65-
<p className={cn('text-sm sm:text-base')}></p>
72+
<p className={cn('text-xl text-muted-foreground sm:text-2xl')}>
73+
<span className={cn('font-semibold text-foreground')}>
74+
Software Engineer 신원세
75+
</span>
76+
입니다
77+
</p>
6678
</section>
67-
<section className={cn('flex flex-col gap-12')}>
68-
<TimeLine className={cn('mt-4')} data={careers} title="Careers" />
69-
<TimeLine className={cn('mt-4')} data={activities} title="Activities" />
70-
<TimeLine className={cn('mt-4')} data={educations} title="Education" />
79+
<section className={cn('flex w-full max-w-4xl flex-col gap-16')}>
80+
<TimeLine data={careers} title="Careers" />
81+
<TimeLine data={activities} title="Activities" />
82+
<TimeLine data={educations} title="Education" />
7183
</section>
7284
</main>
7385
);

src/app/(about)/components/block.tsx

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,33 @@ const Block = ({ blockContent, className }: BlockProps) => {
1717
const { dateRange, department, englishName, koreanName } = blockContent;
1818

1919
return (
20-
<div className={cn(className, 'flex w-full flex-row items-center')}>
21-
<div className={cn('w-32 text-xs sm:w-48 sm:text-base')}>{dateRange}</div>
22-
<div className={cn('flex flex-col')}>
23-
<span className={cn('mr-1 text-sm font-medium sm:text-base')}>
20+
<div
21+
className={cn(
22+
'group flex w-full flex-col gap-3 rounded-xl border border-border/50 bg-card p-5 transition-all duration-300',
23+
'hover:border-border hover:shadow-md hover:shadow-black/5 sm:flex-row sm:items-center sm:gap-6',
24+
'dark:hover:shadow-white/5',
25+
className,
26+
)}
27+
>
28+
<div
29+
className={cn(
30+
'min-w-fit text-sm font-medium text-muted-foreground sm:w-40 sm:text-base',
31+
)}
32+
>
33+
{dateRange}
34+
</div>
35+
<div className={cn('flex flex-1 flex-col gap-1')}>
36+
<span
37+
className={cn(
38+
'text-base font-semibold transition-colors group-hover:text-foreground sm:text-lg',
39+
)}
40+
>
2441
{englishName}
2542
</span>
26-
<span className={cn('text-xs text-neutral-400 sm:text-sm')}>
43+
<span className={cn('text-sm text-muted-foreground')}>
2744
{koreanName}
2845
</span>
29-
<p className={cn('flex flex-row text-xs text-neutral-400 sm:text-sm')}>
30-
<span>{department}</span>
31-
</p>
46+
<p className={cn('text-sm text-muted-foreground/80')}>{department}</p>
3247
</div>
3348
</div>
3449
);

src/app/(about)/components/time-line.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ interface TimeLineProps {
1111

1212
function TimeLine({ className, data, title }: TimeLineProps) {
1313
return (
14-
<section className={cn('flex w-full flex-col items-center', className)}>
15-
<h2 className={cn('text-xl sm:text-3xl')}>{title}</h2>
16-
<div className={cn('flex w-full flex-col gap-4 py-8')}>
14+
<section className={cn('flex w-full flex-col', className)}>
15+
<h2 className={cn('mb-6 text-2xl font-bold tracking-tight sm:text-3xl')}>
16+
{title}
17+
</h2>
18+
<div className={cn('flex w-full flex-col gap-6')}>
1719
{data?.map((career) => {
1820
return (
1921
<Block

src/app/(home)/components/introduction-section.tsx

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,39 @@ import Section from '@/components/section';
44
import { cn } from '@/utils/cn';
55

66
const IntroductionSection = () => {
7-
return (
8-
<Section className={cn('w-full p-6')} layout="flex">
9-
<div className={cn('order-1 mt-2 sm:-order-1 sm:mt-0')}>
10-
<h2 className={cn('mb-2 text-3xl font-bold')}>신원세입니다</h2>
11-
<p>평생 재미있게 개발하고 싶습니다</p>
12-
</div>
13-
<Image
14-
alt="profile"
15-
className={cn('rounded-full')}
16-
height={192}
17-
src="/profile.png"
18-
unoptimized
19-
width={192}
20-
/>
21-
</Section>
22-
);
7+
return (
8+
<Section className={cn('w-full py-16 sm:py-24')} layout="flex">
9+
<div className={cn('order-1 flex flex-col gap-4 sm:-order-1 sm:mt-0')}>
10+
<h1
11+
className={cn(
12+
'text-4xl font-bold leading-tight tracking-tight text-balance sm:text-5xl lg:text-6xl',
13+
'bg-gradient-to-br from-foreground to-foreground/70 bg-clip-text text-transparent',
14+
)}
15+
>
16+
신원세입니다
17+
</h1>
18+
<p className={cn('text-lg text-muted-foreground sm:text-xl')}>
19+
평생 재미있게 개발하고 싶습니다
20+
</p>
21+
</div>
22+
<div className={cn('relative')}>
23+
<div
24+
className={cn(
25+
'absolute -inset-4 rounded-full bg-gradient-to-br from-primary/20 to-primary/5 blur-2xl',
26+
'animate-pulse',
27+
)}
28+
/>
29+
<Image
30+
alt="profile"
31+
className={cn('relative rounded-full ring-2 ring-border/50')}
32+
height={192}
33+
src="/profile.png"
34+
unoptimized
35+
width={192}
36+
/>
37+
</div>
38+
</Section>
39+
);
2340
};
2441

2542
export default IntroductionSection;

src/app/(home)/components/recent-post-section.tsx

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,29 @@ import { getAllPosts } from '@/services/post';
55
import { cn } from '@/utils/cn';
66

77
const RecentPostSection = async () => {
8-
const posts = (await getAllPosts()).slice(0, 3);
8+
const posts = (await getAllPosts()).slice(0, 3);
99

10-
return (
11-
<section className={cn('flex w-full flex-col gap-4 px-6')}>
12-
<h2 className={cn('w-full font-bold')}>최근 포스트</h2>
13-
{posts.map(({ description, slug, title }) => (
14-
<Link key={slug} href={`posts${slug}`}>
15-
<Card description={description} title={title} />
16-
</Link>
17-
))}
18-
</section>
19-
);
10+
return (
11+
<section className={cn('flex w-full flex-col gap-6 py-12')}>
12+
<div className={cn('flex flex-col gap-2')}>
13+
<h2 className={cn('text-2xl font-bold tracking-tight sm:text-3xl')}>
14+
최근 포스트
15+
</h2>
16+
<p className={cn('text-sm text-muted-foreground')}>
17+
최신 글을 확인해보세요
18+
</p>
19+
</div>
20+
<div
21+
className={cn('grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3')}
22+
>
23+
{posts.map(({ description, slug, title }) => (
24+
<Link key={slug} href={`posts${slug}`}>
25+
<Card description={description} title={title} />
26+
</Link>
27+
))}
28+
</div>
29+
</section>
30+
);
2031
};
2132

2233
export default RecentPostSection;

src/app/(home)/page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { cn } from '@/utils/cn';
33
import { IntroductionSection, RecentPostSection } from './components';
44

55
export default function Home() {
6-
return (
7-
<main className={cn('mt-4 flex w-full flex-col items-center gap-12')}>
8-
<IntroductionSection />
9-
<RecentPostSection />
10-
</main>
11-
);
6+
return (
7+
<main className={cn('flex w-full flex-col items-center')}>
8+
<IntroductionSection />
9+
<RecentPostSection />
10+
</main>
11+
);
1212
}

src/app/(post)/posts/[slug]/page.tsx

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,43 @@ async function Post({ params }: { params: Params }) {
5454
await Promise.resolve(getPost(slug));
5555

5656
return (
57-
<main className={cn('mb-4 flex w-full flex-col gap-4 px-6 py-2')}>
58-
<div className={cn('border-b')}>
59-
<div className={cn('mb-4 flex flex-row gap-1')}>
60-
{category.map((item: Category) => (
61-
<TagChip key={item.id} color={item.color} label={item.name} />
62-
))}
63-
</div>
64-
<h1 className={cn('mb-1 text-2xl')}>{title}</h1>
65-
<p className={cn('mb-4 text-neutral-400')}>{description}</p>
66-
<p className={cn('text-neutral-400')}>
67-
{lastEditedTime.format('YYYY-MM-DD')}
68-
</p>
69-
</div>
70-
<TableOfContents toc={toc} />
71-
{/* biome-ignore lint/security/noDangerouslySetInnerHtml: This is Notion content */}
72-
<div dangerouslySetInnerHTML={{ __html: content }} id="post" />
73-
<Giscus />
57+
<main className={cn('flex w-full flex-col items-center py-12')}>
58+
<article className={cn('w-full max-w-3xl')}>
59+
<header
60+
className={cn(
61+
'mb-12 flex flex-col gap-6 border-b border-border/40 pb-8',
62+
)}
63+
>
64+
<div className={cn('flex flex-row flex-wrap gap-2')}>
65+
{category.map((item: Category) => (
66+
<TagChip key={item.id} color={item.color} label={item.name} />
67+
))}
68+
</div>
69+
<h1
70+
className={cn(
71+
'text-3xl font-bold leading-tight tracking-tight text-balance sm:text-4xl lg:text-5xl',
72+
'bg-gradient-to-br from-foreground to-foreground/80 bg-clip-text',
73+
)}
74+
>
75+
{title}
76+
</h1>
77+
<p className={cn('text-lg text-muted-foreground leading-relaxed')}>
78+
{description}
79+
</p>
80+
<time className={cn('text-sm text-muted-foreground/80')}>
81+
{lastEditedTime.format('YYYY년 MM월 DD일')}
82+
</time>
83+
</header>
84+
<TableOfContents toc={toc} />
85+
{/* biome-ignore lint/security/noDangerouslySetInnerHtml: Notion content requires HTML rendering */}
86+
{/* biome-ignore lint/a11y/useValidAriaValues: Static ID used for post styling */}
87+
<div
88+
className={cn('prose prose-lg dark:prose-invert max-w-none')}
89+
dangerouslySetInnerHTML={{ __html: content }}
90+
id="post"
91+
/>
92+
<Giscus />
93+
</article>
7494
</main>
7595
);
7696
}

src/app/(post)/posts/components/table-of-contents.tsx

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,55 @@ import type { TOCItem } from '@/types/notion';
66
import { cn } from '@/utils/cn';
77

88
type Props = {
9-
toc: TOCItem[];
9+
toc: TOCItem[];
1010
};
1111

1212
const TableOfContents = ({ toc }: Props) => {
13-
if (toc.length === 0) {
14-
return null;
15-
}
13+
if (toc.length === 0) {
14+
return null;
15+
}
1616

17-
const handleClick = (e: MouseEvent<HTMLAnchorElement>, id: string) => {
18-
e.preventDefault();
19-
document.querySelector(`#${id}`)?.scrollIntoView({ behavior: 'smooth' });
20-
};
17+
const handleClick = (e: MouseEvent<HTMLAnchorElement>, id: string) => {
18+
e.preventDefault();
19+
document.querySelector(`#${id}`)?.scrollIntoView({ behavior: 'smooth' });
20+
};
2121

22-
return (
23-
<div
24-
className={cn('border-l-2 border-stone-600 pl-4 text-sm text-stone-400')}
25-
>
26-
<ul>
27-
{toc.map(({ id, tagName, text }) => (
28-
<li
29-
key={text + id}
30-
className={cn(
31-
'w-full py-1',
32-
tagName === 'h2' && 'pl-4',
33-
tagName === 'h3' && 'pl-8',
34-
)}
35-
>
36-
<a
37-
className={cn(
38-
'block truncate transition-colors hover:text-stone-200',
39-
)}
40-
href={`#${id}`}
41-
onClick={(e) => handleClick(e, id)}
42-
>
43-
{text}
44-
</a>
45-
</li>
46-
))}
47-
</ul>
48-
</div>
49-
);
22+
return (
23+
<nav
24+
className={cn('my-8 rounded-xl border border-border/50 bg-muted/30 p-6')}
25+
>
26+
<h2
27+
className={cn(
28+
'mb-4 text-sm font-semibold uppercase tracking-wider text-muted-foreground',
29+
)}
30+
>
31+
목차
32+
</h2>
33+
<ul className={cn('space-y-2')}>
34+
{toc.map(({ id, tagName, text }) => (
35+
<li
36+
key={text + id}
37+
className={cn(
38+
'w-full',
39+
tagName === 'h2' && 'pl-0',
40+
tagName === 'h3' && 'pl-4',
41+
)}
42+
>
43+
<a
44+
className={cn(
45+
'block truncate text-sm transition-colors hover:text-foreground',
46+
'text-muted-foreground',
47+
)}
48+
href={`#${id}`}
49+
onClick={(e) => handleClick(e, id)}
50+
>
51+
{text}
52+
</a>
53+
</li>
54+
))}
55+
</ul>
56+
</nav>
57+
);
5058
};
5159

5260
export default TableOfContents;

0 commit comments

Comments
 (0)