Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions app/entities/portfolio/PortfolioPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const PortfolioPreview = ({

return (
<div
className="bg-white dark:bg-neutral-800 rounded-lg overflow-hidden shadow-sm hover:shadow-lg transition-shadow duration-300"
className="group bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-2xl overflow-hidden shadow transition-all duration-300 border border-gray-200 dark:border-gray-700"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
Expand All @@ -50,7 +50,7 @@ const PortfolioPreview = ({
src={project.image}
alt={`${project.title} 프로젝트 이미지`}
className={`w-full aspect-video object-cover transition-transform duration-500 ${
showOverlay ? 'scale-105' : 'scale-100'
showOverlay ? 'scale-110' : 'scale-100'
}`}
/>

Expand Down Expand Up @@ -140,22 +140,22 @@ const PortfolioPreview = ({
</div>
</div>

<div className="p-4 md:p-6">
<div className="p-6 md:p-8">
<Link href={project.slug ? `/portfolio/${project.slug}` : '#'}>
<h3 className="text-lg md:text-xl font-bold mb-2 hover:text-emerald-500 transition-colors line-clamp-2">
<h3 className="text-xl md:text-2xl font-bold mb-3 text-gray-900 dark:text-gray-100 hover:text-gray-600 dark:hover:text-gray-400 transition-colors line-clamp-2">
{project.title}
</h3>
</Link>
<p className="text-sm text-gray-600 dark:text-gray-300 mb-3 md:mb-4 line-clamp-3">
<p className="text-sm md:text-base text-gray-600 dark:text-gray-300 mb-4 md:mb-5 line-clamp-3 leading-relaxed">
{project.description}
</p>

{!hideTags && project.tags && project.tags.length > 0 && (
<div className="flex flex-wrap gap-1.5 md:gap-2 mt-3">
<div className="flex flex-wrap gap-2 mt-4">
{project.tags.map((tag, index) => (
<span
key={index}
className="text-xs px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded-full text-gray-700 dark:text-gray-300 whitespace-nowrap"
className="text-xs px-3 py-1.5 bg-gray-200 dark:bg-gray-700 rounded-full text-gray-700 dark:text-gray-300 whitespace-nowrap font-medium"
>
{tag}
</span>
Expand All @@ -164,15 +164,15 @@ const PortfolioPreview = ({
)}

{/* 모바일 하단 액션 버튼들 */}
<div className="flex md:hidden gap-2 mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
<div className="flex md:hidden gap-2 mt-5 pt-4 border-t border-gray-200 dark:border-gray-700">
{project.demoUrl && (
<Link
href={project.demoUrl}
target="_blank"
rel="noopener noreferrer"
className="flex-1"
>
<button className="inline-flex items-center justify-center gap-1 w-full bg-neutral-100 dark:bg-neutral-700 hover:bg-neutral-200 dark:hover:bg-neutral-600 text-neutral-700 dark:text-neutral-200 px-3 py-2 rounded-md transition-colors text-xs">
<button className="inline-flex items-center justify-center gap-1.5 w-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-3 py-2.5 rounded-lg transition-colors text-xs font-medium">
<FaGlobe size={12} />
배포
</button>
Expand All @@ -185,7 +185,7 @@ const PortfolioPreview = ({
rel="noopener noreferrer"
className="flex-1"
>
<button className="inline-flex items-center justify-center gap-1 w-full bg-neutral-100 dark:bg-neutral-700 hover:bg-neutral-200 dark:hover:bg-neutral-600 text-neutral-700 dark:text-neutral-200 px-3 py-2 rounded-md transition-colors text-xs">
<button className="inline-flex items-center justify-center gap-1.5 w-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-gray-200 px-3 py-2.5 rounded-lg transition-colors text-xs font-medium">
<FaGithub size={12} />
코드
</button>
Expand All @@ -197,7 +197,7 @@ const PortfolioPreview = ({
rel="noopener noreferrer"
className="flex-1"
>
<button className="w-full bg-emerald-100 dark:bg-emerald-800 hover:bg-emerald-200 dark:hover:bg-emerald-700 text-emerald-700 dark:text-emerald-200 px-3 py-2 rounded-md transition-colors text-xs">
<button className="w-full bg-gray-800 dark:bg-gray-200 hover:bg-gray-700 dark:hover:bg-gray-300 text-gray-100 dark:text-gray-900 px-3 py-2.5 rounded-lg transition-colors text-xs font-medium">
자세히
</button>
</Link>
Expand Down
211 changes: 142 additions & 69 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Post } from '@/app/types/Post';
import ErrorBox from '@/app/entities/common/Error/ErrorBox';
import { useRouter } from 'next/navigation';
import useShortcut from '@/app/hooks/common/useShortcut';
import DecryptedText from './entities/bits/DecryptedText';

export default function Home() {
const { fingerprint } = useFingerprint();
Expand Down Expand Up @@ -58,95 +59,163 @@ export default function Home() {
useShortcut(goToPostsPage, ['Ctrl', ';'], true);

return (
<main className="w-full max-w-4xl mx-auto grid gap-16 p-4 md:p-8">
<section className="grid gap-6">
<div className="relative h-64 w-full overflow-hidden rounded-lg">
<main className="w-full max-w-6xl mx-auto grid gap-16 p-4 md:p-8">
{/* Hero Section */}
<section className="grid gap-4">
<div className="relative h-80 md:h-96 w-full overflow-hidden rounded-2xl shadow-2xl group">
<Image
src={profileBackground}
priority={true}
width={'1024'}
height={'720'}
alt="Hero image"
className="object-cover bg-gray-100 w-full h-full"
className="object-cover bg-gray-100 w-full h-full transition-transform duration-700 group-hover:scale-105"
/>
<div className="absolute inset-0 bg-black/10"></div>
<div
className={
'absolute top-0 left-0 p-8 w-full h-full flex flex-col gap-2 text-white '
}
>
<h1 className=" text-4xl font-bold ">Frontend Developer</h1>
<p className={'text-xl '}>
<span className="text-sm font-bold">Jeongwoo Seo</span>
</p>
<div className={' flex flex-col justify-end flex-grow'}>
<div>React · NextJS · TypeScript</div>
<div className="absolute inset-0 bg-gradient-to-br from-black/40 via-black/20 to-transparent"></div>
<div className="absolute top-0 left-0 p-8 md:p-12 w-full h-full flex flex-col gap-3 text-white">
<div className="space-y-2">
<h1 className="text-5xl md:text-6xl font-bold tracking-tight">
<DecryptedText
text="Frontend Developer"
speed={60}
animateOn="view"
revealDirection="start"
sequential
encryptedClassName="text-neutral-200/90"
/>
</h1>
<p className="text-xl md:text-2xl font-light opacity-90">
Jeongwoo Seo
</p>
</div>
<div className="flex flex-col justify-end flex-grow">
<div className="flex flex-wrap gap-3 text-sm md:text-base font-medium">
<span className="px-4 py-2 bg-white/20 backdrop-blur-sm rounded-full border border-white/30">
React
</span>
<span className="px-4 py-2 bg-white/20 backdrop-blur-sm rounded-full border border-white/30">
NextJS
</span>
<span className="px-4 py-2 bg-white/20 backdrop-blur-sm rounded-full border border-white/30">
TypeScript
</span>
</div>
</div>
</div>
</div>
<p className="text-lg text-default max-w-2xl">
안녕하세요, 서정우입니다. 사용자 경험과 깔끔한 코드 작성에 중점을 두고
있으며, 멈추지 않는 기술의 변화를 즐깁니다.

<p className="text-lg md:text-xl text-default max-w-3xl mx-auto text-center mt-4">
안녕하세요, 서정우입니다.
</p>
<p className="text-lg md:text-xl text-default max-w-3xl mx-auto text-center mb-4">
깔끔한 코드 작성에 중점을 두고, 확장성에 대해 고민하며 멈추지 않는
기술의 변화를 즐깁니다.
</p>
</section>

<section className="grid md:grid-cols-2 gap-8 items-center">
<div className="relative h-64 overflow-hidden rounded-lg">
<Image
width={500}
height={400}
priority={true}
src={'/images/profile/profile.jpg'}
alt="About image"
className="hover:rotate-180 transition duration-[60000ms] object-cover w-full h-full bg-gray-500"
/>
</div>
<div className="grid gap-4">
<h2 className="text-2xl font-semibold">About Me</h2>
<p className="text-default">
프론트엔드 개발자로서 React, Next.js, TypeScript를 주로 사용합니다.
항상 사용자 입장에서 생각하고, 성능 최적화에 관심이 많으며, 지속적인
학습과 성장을 추구합니다.
</p>
<div className="flex gap-4">
<a href={githubLink} target={'_blank'}>
<FaGithub className="w-5 h-5 text-default hover:scale-125 transition cursor-pointer" />
</a>
<a href={linkedinLink} target={'_blank'}>
<FaLinkedin className="w-5 h-5 text-default hover:scale-125 transition cursor-pointer" />
</a>
<section className="relative overflow-hidden rounded-2xl bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 p-8 md:p-12">
<div className="grid md:grid-cols-[1fr,2fr] gap-8 md:gap-12 items-center">
<div className="relative mx-auto md:mx-0">
<div className="absolute -inset-1 bg-gradient-to-r from-gray-300 to-gray-400 dark:from-gray-600 dark:to-gray-700 rounded-full blur opacity-20 animate-pulse"></div>
<div className="relative h-56 w-56 overflow-hidden rounded-full ring-4 ring-white dark:ring-gray-700 shadow-xl">
<Image
width={500}
height={400}
priority={true}
src={'/images/profile/profile.jpg'}
alt="About image"
className="hover:scale-110 transition duration-700 object-cover w-full h-full bg-gray-500"
/>
</div>
</div>
<div className="grid gap-6">
<div className="space-y-2">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 dark:text-gray-100">
About Me
</h2>
<div className="h-1 w-20 bg-gray-900 dark:bg-gray-100 rounded-full"></div>
</div>
<p className="text-default text-lg leading-relaxed">
프론트엔드 개발자로서 React, Next.js, TypeScript를 주로
사용합니다. 항상 사용자 입장에서 생각하고, 성능 최적화에 관심이
많으며, 지속적인 학습과 성장을 추구합니다.
</p>
<div className="flex gap-4 pt-2">
<a
href={githubLink}
target={'_blank'}
className="p-3 rounded-full bg-white dark:bg-gray-800 shadow-md hover:shadow-xl hover:scale-110 transition-all duration-300"
>
<FaGithub className="w-6 h-6 text-gray-700 dark:text-gray-300" />
</a>
<a
href={linkedinLink}
target={'_blank'}
className="p-3 rounded-full bg-white dark:bg-gray-800 shadow-md hover:shadow-xl hover:scale-110 transition-all duration-300"
>
<FaLinkedin className="w-6 h-6 text-gray-700 dark:text-gray-300" />
</a>
</div>
</div>
</div>
</section>

<section className="grid gap-6">
<h2 className="text-2xl font-semibold">Featured Projects</h2>
<div className={'grid grid-cols-1 md:grid-cols-2 gap-6'}>
<section className="grid gap-8">
<div className="space-y-2">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 dark:text-gray-100">
Featured Projects
</h2>
<div className="h-1 w-24 bg-gray-900 dark:bg-gray-100 rounded-full"></div>
</div>
<div className={'grid grid-cols-1 md:grid-cols-2 gap-8'}>
{projects.map((project) => {
return <PortfolioPreview key={project.title} project={project} />;
})}
</div>
</section>

<section className="grid gap-6">
<h2 className="text-2xl font-semibold">Latest Articles</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<section className="grid gap-8">
<div className="space-y-2">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 dark:text-gray-100">
Latest Articles
</h2>
<div className="h-1 w-24 bg-gray-900 dark:bg-gray-100 rounded-full"></div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{loading ? (
<>
<div className={'flex flex-col gap-2'}>
<Skeleton className={'w-full h-48'} />
<Skeleton className={'w-full h-6'} />
<Skeleton className={'w-3/4 h-4'} />
<div
className={
'flex flex-col gap-3 bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-2xl overflow-hidden shadow-2xl border border-gray-200 dark:border-gray-700'
}
>
<Skeleton className={'w-full h-52 rounded-none'} />
<div className="p-6 space-y-3">
<Skeleton className={'w-full h-7'} />
<Skeleton className={'w-3/4 h-5'} />
</div>
</div>
<div className={'flex flex-col gap-2'}>
<Skeleton className={'w-full h-48'} />
<Skeleton className={'w-full h-6'} />
<Skeleton className={'w-3/4 h-4'} />
<div
className={
'flex flex-col gap-3 bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-2xl overflow-hidden shadow-2xl border border-gray-200 dark:border-gray-700'
}
>
<Skeleton className={'w-full h-52 rounded-none'} />
<div className="p-6 space-y-3">
<Skeleton className={'w-full h-7'} />
<Skeleton className={'w-3/4 h-5'} />
</div>
</div>
<div className={'flex flex-col gap-2'}>
<Skeleton className={'w-full h-48'} />
<Skeleton className={'w-full h-6'} />
<Skeleton className={'w-3/4 h-4'} />
<div
className={
'flex flex-col gap-3 bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-2xl overflow-hidden shadow-2xl border border-gray-200 dark:border-gray-700'
}
>
<Skeleton className={'w-full h-52 rounded-none'} />
<div className="p-6 space-y-3">
<Skeleton className={'w-full h-7'} />
<Skeleton className={'w-3/4 h-5'} />
</div>
</div>
</>
) : (
Expand All @@ -155,9 +224,9 @@ export default function Home() {
<Link
href={`/posts/${post.slug}`}
key={post._id}
className="group cursor-pointer"
className="group cursor-pointer bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-2xl overflow-hidden shadow transition-all duration-300 border border-gray-200 dark:border-gray-700 hover:scale-[1.02]"
>
<div className="relative h-48 mb-4 overflow-hidden rounded-lg hover:shadow-lg">
<div className="relative h-52 overflow-hidden">
<Image
width={500}
height={400}
Expand All @@ -166,13 +235,17 @@ export default function Home() {
'/images/placeholder/thumbnail_example2.webp'
}
alt={`Article ${post.title}`}
className="object-cover bg-[position:50%_20%] bg-cover bg-no-repeat w-full h-full transition-transform group-hover:scale-105 bg-gray-500 "
className="object-cover bg-[position:50%_20%] bg-cover bg-no-repeat w-full h-full transition-transform duration-500 group-hover:scale-110 bg-gray-500"
/>
</div>
<h3 className="font-medium mb-2">{post.title}</h3>
<p className="text-sm text-default">
{post.subTitle && post.subTitle.slice(0, 80)}
</p>
<div className="p-6">
<h3 className="text-lg font-bold mb-2 text-gray-900 dark:text-gray-100 line-clamp-2 group-hover:text-gray-600 dark:group-hover:text-gray-400 transition-colors">
{post.title}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-300 line-clamp-3 leading-relaxed">
{post.subTitle && post.subTitle.slice(0, 80)}
</p>
</div>
</Link>
))
)}
Expand Down
2 changes: 0 additions & 2 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,10 @@ const config: Config = {
slideUp: {
'0%': {
transform: 'translateY(50%)',
width: '20%',
opacity: '0',
},
'100%': {
transform: 'translateY(0)',
width: '100%',
opacity: '1',
},
},
Expand Down