1- import Image from 'next/image' ;
21import Link from 'next/link' ;
32import { clsx } from 'clsx' ;
43import { FeedData } from '@/domains/post/model/types' ;
4+ import { CategoryIcon } from '@/shared/ui/icons/AppSectionIcon' ;
55
66interface PostCardProps {
77 post : FeedData ;
88 variant ?: 'default' | 'featured' | 'list' ;
99}
1010
11- function CategoryIcon ( { category } : { category : string } ) {
12- switch ( category ) {
13- case 'Tech' :
14- return (
15- < svg
16- viewBox = "0 0 24 24"
17- width = "12"
18- height = "12"
19- fill = "none"
20- stroke = "currentColor"
21- strokeWidth = "2"
22- strokeLinecap = "round"
23- strokeLinejoin = "round"
24- aria-hidden = "true"
25- >
26- < rect x = "3" y = "4" width = "18" height = "14" rx = "2" />
27- < path d = "M8 20h8" />
28- < path d = "M10 16v4" />
29- < path d = "M14 16v4" />
30- </ svg >
31- ) ;
32- case 'Life' :
33- return (
34- < svg
35- viewBox = "0 0 24 24"
36- width = "12"
37- height = "12"
38- fill = "none"
39- stroke = "currentColor"
40- strokeWidth = "2"
41- strokeLinecap = "round"
42- strokeLinejoin = "round"
43- aria-hidden = "true"
44- >
45- < path d = "M4 5a2 2 0 0 1 2-2h12v18H6a2 2 0 0 1-2-2z" />
46- < path d = "M8 7h7" />
47- < path d = "M8 11h7" />
48- </ svg >
49- ) ;
50- default :
51- return (
52- < svg
53- viewBox = "0 0 24 24"
54- width = "12"
55- height = "12"
56- fill = "none"
57- stroke = "currentColor"
58- strokeWidth = "2"
59- strokeLinecap = "round"
60- strokeLinejoin = "round"
61- aria-hidden = "true"
62- >
63- < path d = "m20 12-8 8-8-8 8-8 8 8z" />
64- </ svg >
65- ) ;
66- }
67- }
68-
6911export default function PostCard ( { post, variant = 'default' } : PostCardProps ) {
7012 const formattedDate = new Date ( post . date ) . toLocaleDateString ( 'ko-KR' , {
7113 year : 'numeric' ,
@@ -108,15 +50,15 @@ export default function PostCard({ post, variant = 'default' }: PostCardProps) {
10850 < Link
10951 href = { `/blog/${ post . slug } ` }
11052 className = { clsx (
111- 'group block rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-bg-primary)] px-4 py-4 ' ,
53+ 'group block overflow-hidden rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-bg-primary)] px-5 py-5 sm:px-6 ' ,
11254 'transition-all duration-[var(--duration-200)] ease-[var(--ease-default)]' ,
113- 'hover:border-[var(--color-border-hover)] hover:bg-[var(--color-grey-50)]' ,
55+ 'hover:-translate-y-0.5 hover: border-[var(--color-border-hover)] hover:bg-[var(--color-grey-50)] hover:shadow-[var(--shadow-sm )]' ,
11456 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-toss-blue)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg-primary)]'
11557 ) }
11658 >
117- < div className = "flex items-center justify-between gap-4 " >
118- < div className = "min-w-0 flex-1 " >
119- < div className = "flex flex-wrap items-center gap-2 text-xs text-[var(--color-text-tertiary)]" >
59+ < div className = "min-w-0 " >
60+ < div className = "min-w-0" >
61+ < div className = "flex flex-wrap items-center gap-2 text-xs text-[var(--color-text-tertiary)] transition-transform duration-300 ease-[var(--ease-default)] group-hover:translate-x-0.5 " >
12062 < span className = "inline-flex items-center gap-1.5 rounded-full border border-[var(--color-border)] bg-[var(--color-grey-50)] px-2 py-1 text-xs font-medium text-[var(--color-text-secondary)]" >
12163 < CategoryIcon category = { post . category } />
12264 { post . category }
@@ -135,14 +77,14 @@ export default function PostCard({ post, variant = 'default' }: PostCardProps) {
13577 </ >
13678 ) }
13779 </ div >
138- < h3 className = "mt-2 text-base font-semibold leading-snug text-[var(--color-text-primary)] transition-colors group-hover:text-[var(--color-toss-blue)] group-focus-visible:text-[var(--color-toss-blue)]" >
80+ < h3 className = "mt-3 text-lg font-semibold leading-snug text-[var(--color-text-primary)] transition-[color,transform] duration-300 ease-[var(--ease-default)] group-hover:translate-x-1 group-hover:text-[var(--color-toss-blue)] group-focus-visible:text-[var(--color-toss-blue)]" >
13981 { post . title }
14082 </ h3 >
141- < p className = "mt-1 text-sm text-[var(--color-text-secondary)] line-clamp-2" >
83+ < p className = "mt-2 max-w-3xl text-sm leading-6 text-[var(--color-text-secondary)] line-clamp-2 transition-transform duration-300 ease-[var(--ease-default)] group-hover:translate-x-1 " >
14284 { post . description }
14385 </ p >
14486 { visibleTags . length > 0 ? (
145- < div className = "mt-3 flex flex-wrap gap-2" >
87+ < div className = "mt-3 flex flex-wrap gap-2 transition-transform duration-300 ease-[var(--ease-default)] group-hover:translate-x-1 " >
14688 { visibleTags . map ( ( tag ) => (
14789 < span
14890 key = { tag }
@@ -154,18 +96,6 @@ export default function PostCard({ post, variant = 'default' }: PostCardProps) {
15496 </ div >
15597 ) : null }
15698 </ div >
157- { post . image ? (
158- < div className = "hidden h-20 w-32 shrink-0 overflow-hidden rounded-xl border border-[var(--color-border)] sm:block" >
159- < Image
160- src = { post . image }
161- alt = ""
162- width = { 256 }
163- height = { 160 }
164- sizes = "128px"
165- className = "h-full w-full object-cover transition-transform duration-200 group-hover:scale-105"
166- />
167- </ div >
168- ) : null }
16999 </ div >
170100 </ Link >
171101 ) ;
@@ -175,14 +105,14 @@ export default function PostCard({ post, variant = 'default' }: PostCardProps) {
175105 < Link
176106 href = { `/blog/${ post . slug } ` }
177107 className = { clsx (
178- 'group flex h-full cursor-pointer flex-col rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-bg-primary)] p-6' ,
108+ 'group flex h-full cursor-pointer flex-col overflow-hidden rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-bg-primary)] p-6' ,
179109 'transition-all duration-[var(--duration-200)] ease-[var(--ease-default)]' ,
180110 'hover:-translate-y-0.5 hover:border-[var(--color-border-hover)] hover:shadow-[var(--shadow-md)]' ,
181111 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-toss-blue)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg-primary)]' ,
182112 'active:translate-y-0 active:shadow-sm'
183113 ) }
184114 >
185- < div className = "mb-4 flex items-center gap-2 text-xs text-[var(--color-text-tertiary)]" >
115+ < div className = "mb-4 flex items-center gap-2 text-xs text-[var(--color-text-tertiary)] transition-transform duration-300 ease-[var(--ease-default)] group-hover:translate-x-0.5 " >
186116 < span className = "inline-flex items-center gap-1.5 rounded-full border border-[var(--color-border)] bg-[var(--color-grey-50)] px-2.5 py-1 text-xs font-medium text-[var(--color-text-secondary)]" >
187117 < CategoryIcon category = { post . category } />
188118 { post . category }
@@ -196,10 +126,10 @@ export default function PostCard({ post, variant = 'default' }: PostCardProps) {
196126 </ >
197127 ) }
198128 </ div >
199- < h3 className = "line-clamp-2 text-lg font-semibold leading-snug text-[var(--color-text-primary)] transition-colors group-hover:text-[var(--color-toss-blue)] group-focus-visible:text-[var(--color-toss-blue)]" >
129+ < h3 className = "line-clamp-2 text-lg font-semibold leading-snug text-[var(--color-text-primary)] transition-[color,transform] duration-300 ease-[var(--ease-default)] group-hover:translate-x-1 group-hover:text-[var(--color-toss-blue)] group-focus-visible:text-[var(--color-toss-blue)]" >
200130 { post . title }
201131 </ h3 >
202- < p className = "mt-3 flex-grow line-clamp-2 text-sm text-[var(--color-text-secondary)]" >
132+ < p className = "mt-3 flex-grow line-clamp-2 text-sm text-[var(--color-text-secondary)] transition-transform duration-300 ease-[var(--ease-default)] group-hover:translate-x-1 " >
203133 { post . description }
204134 </ p >
205135 </ Link >
0 commit comments