11import React from 'react' ;
2- import { Link , useLocation } from 'react-router-dom' ; // Import useLocation
3- import { useAnimation } from '../context/AnimationContext' ; // Import useAnimation
2+ import { Link } from 'react-router-dom' ;
3+ import { motion } from 'framer-motion' ;
4+ import { ArrowRight } from '@phosphor-icons/react' ;
45
56const PostItem = ( {
67 slug,
@@ -11,143 +12,99 @@ const PostItem = ({
1112 series,
1213 seriesIndex,
1314 isSeries,
14- authors, // Change to authors array
15+ isActive,
16+ onHover = ( ) => { } ,
1517} ) => {
16- const {
17- isAnimationEnabled,
18- showAnimationsHomepage,
19- showAnimationsInnerPages,
20- } = useAnimation ( ) ; // Use the animation context
21- const location = useLocation ( ) ; // Get current location
22-
23- // Format the date to a shorter format: Month Day, Year
24- const formattedDate = new Date ( date ) . toLocaleDateString ( 'en-US' , {
25- month : 'short' ,
26- day : 'numeric' ,
27- year : 'numeric' ,
18+ const formattedDate = new Date ( date ) . toLocaleDateString ( 'en-GB' , {
19+ day : '2-digit' ,
20+ month : '2-digit' ,
21+ year : '2-digit' ,
2822 } ) ;
2923
30- // Format the updated date if it exists
31- const formattedUpdatedDate = updatedDate
32- ? new Date ( updatedDate ) . toLocaleDateString ( 'en-US' , {
33- month : 'short' ,
34- day : 'numeric' ,
35- year : 'numeric' ,
36- } )
37- : null ;
38-
39- const categoryBadgeColorStyle = {
40- backgroundColor :
41- category === 'dev'
42- ? 'var(--color-dev-badge)'
43- : category === 'series'
44- ? 'var(--color-series-badge)'
45- : category === 'd&d'
46- ? 'var(--color-dnd-badge)'
47- : category === 'gist'
48- ? 'var(--color-gist-badge)'
49- : category === 'feat'
50- ? 'var(--color-feat-badge)'
51- : 'var(--color-rant-badge)' ,
52- } ;
53-
54- const postBackgroundColorClass =
55- category === 'dev'
56- ? 'bg-dev-card-bg'
57- : category === 'series'
58- ? 'bg-series-card-bg'
59- : category === 'd&d'
60- ? 'bg-dnd-card-bg'
61- : category === 'gist'
62- ? 'bg-gist-card-bg'
63- : category === 'feat'
64- ? 'bg-feat-card-bg'
65- : 'bg-rant-card-bg' ;
66-
67- const postHoverBackgroundColorClass =
24+ const categoryColor =
6825 category === 'dev'
69- ? 'hover:bg-dev-card-bg-hover '
26+ ? 'var(--color-dev-badge) '
7027 : category === 'series'
71- ? 'hover:bg-series-card-bg-hover '
28+ ? 'var(--color-series-badge) '
7229 : category === 'd&d'
73- ? 'hover:bg-dnd-card-bg-hover '
30+ ? 'var(--color-dnd-badge) '
7431 : category === 'gist'
75- ? 'hover:bg-gist-card-bg-hover '
32+ ? 'var(--color-gist-badge) '
7633 : category === 'feat'
77- ? 'hover:bg-feat-card-bg-hover'
78- : 'hover:bg-rant-card-bg-hover' ;
79-
80- const postTitleHoverColorClass =
81- category === 'dev'
82- ? 'group-hover:text-[var(--title-hover-dev)]'
83- : category === 'series'
84- ? 'group-hover:text-[var(--title-hover-series)]'
85- : category === 'd&d'
86- ? 'group-hover:text-[var(--title-hover-dnd)]'
87- : category === 'gist'
88- ? 'group-hover:text-[var(--title-hover-gist)]'
89- : category === 'feat'
90- ? 'group-hover:text-[var(--title-hover-feat)]'
91- : 'group-hover:text-[var(--title-hover-rant)]' ;
92-
93- const categoryBadgeFontColorStyle =
94- category === 'gist' || category === 'gist' ? 'text-black' : 'text-white' ;
95- const shouldAnimate =
96- isAnimationEnabled &&
97- ( ( location . pathname === '/' && showAnimationsHomepage ) ||
98- ( location . pathname !== '/' && showAnimationsInnerPages ) ) ;
34+ ? 'var(--color-feat-badge)'
35+ : 'var(--color-rant-badge)' ;
9936
10037 return (
101- < Link
102- to = { `/blog/${ slug } ` }
103- className = { `block p-8 my-4 border border-gray-700/50 rounded-lg shadow-lg cursor-pointer transition-colors group relative overflow-hidden ${ postBackgroundColorClass } ${ postHoverBackgroundColorClass } ${ shouldAnimate ? 'animated-grid-bg' : '' } ` }
38+ < motion . div
39+ initial = { { opacity : 0 , x : - 10 } }
40+ animate = { { opacity : 1 , x : 0 } }
41+ onMouseEnter = { ( ) => onHover ( { slug, title, date, updatedDate, category, series, seriesIndex, isSeries } ) }
42+ className = "relative mr-4 md:mr-12"
10443 >
105- < article >
106- < div className = "flex items-center" >
107- < p className = "text-sm text-gray-400 w-28 flex-shrink-0" >
44+ < Link
45+ to = { isSeries ? `/blog/series/${ slug } ` : `/blog/${ slug } ` }
46+ className = "group relative flex items-center justify-between border-b border-white/10 py-6 pr-12 transition-all duration-300"
47+ >
48+ { /* Active Marker */ }
49+ < div
50+ className = { `absolute left-0 top-0 h-full w-1 bg-emerald-400 transition-all duration-300 ${
51+ isActive ? 'opacity-100' : 'opacity-0'
52+ } `}
53+ />
54+
55+ < div className = "flex flex-1 items-baseline gap-6 pl-4 md:pl-8 min-w-0" >
56+ { /* Date */ }
57+ < span
58+ className = { `font-mono text-[10px] tracking-widest flex-shrink-0 transition-colors duration-300 ${
59+ isActive ? 'text-emerald-400' : 'text-gray-600'
60+ } `}
61+ >
10862 { formattedDate }
109- { authors && authors . length > 0 && (
110- < span className = "block text-xs text-gray-500" >
111- by { authors [ 0 ] }
112- </ span >
113- ) }
114- </ p >
115- < div className = "ml-4 flex-grow flex items-center" >
116- { category && (
117- < span
118- className = { `mr-2 px-2 py-1 font-arvo text-xs ${ categoryBadgeFontColorStyle } rounded-md hidden sm:inline-block w-16 text-center` }
119- style = { categoryBadgeColorStyle }
120- >
121- { category }
122- </ span >
123- ) }
124- { series && isSeries === undefined && (
125- < span className = "mr-2 px-2 py-1 text-xs font-medium text-blue-400 bg-blue-400/10 rounded-full" >
126- { series } - Part { seriesIndex }
127- </ span >
128- ) }
129- < h2
130- className = { `text-lg font-mono text-white ${ postTitleHoverColorClass } group-hover:underline transition-colors` }
63+ </ span >
64+
65+ { /* Title Area */ }
66+ < div className = "flex flex-col gap-1 min-w-0 flex-1" >
67+ < h3
68+ className = { `text-xl font-medium uppercase tracking-tight transition-all duration-300 md:text-2xl break-words leading-tight ${
69+ isActive
70+ ? 'translate-x-1 text-white'
71+ : 'text-gray-500 group-hover:text-gray-300'
72+ } `}
13173 >
13274 { title }
133- </ h2 >
75+ </ h3 >
76+
77+ { series && (
78+ < span className = "font-mono text-[9px] uppercase tracking-[0.2em] text-emerald-500/60" >
79+ { series } // Part { seriesIndex }
80+ </ span >
81+ ) }
13482 </ div >
135- { formattedUpdatedDate && updatedDate !== date && (
136- < span className = "hidden sm:inline-block ml-4 px-2 py-1 text-xs font-medium text-orange-400 bg-orange-400/10 rounded-full" >
137- Update: { formattedUpdatedDate }
138- </ span >
139- ) }
83+ </ div >
84+
85+ { /* Category Badge */ }
86+ < div className = "flex items-center gap-4" >
14087 < span
141- className = { `ml-4 flex-shrink-0 text-sm font-medium text-primary-400 ${ postTitleHoverColorClass } group-hover:underline transition-colors` }
88+ className = "px-2 py-0.5 text-[9px] font-mono font-bold uppercase tracking-widest border rounded-sm transition-all duration-300"
89+ style = { {
90+ color : categoryColor ,
91+ borderColor : `${ categoryColor } 44` ,
92+ backgroundColor : isActive ? `${ categoryColor } 11` : 'transparent'
93+ } }
14294 >
143- < span className = "hidden sm:inline" >
144- { isSeries ? 'View Series' : 'Read post' }
145- </ span > { ' ' }
146- →
95+ { category || 'Post' }
14796 </ span >
97+
98+ < ArrowRight
99+ weight = "bold"
100+ size = { 20 }
101+ className = { `transition-all duration-300 ${
102+ isActive ? 'translate-x-0 opacity-100 text-emerald-400' : '-translate-x-4 opacity-0 text-gray-500'
103+ } `}
104+ />
148105 </ div >
149- </ article >
150- </ Link >
106+ </ Link >
107+ </ motion . div >
151108 ) ;
152109} ;
153110
0 commit comments