|
| 1 | +import React from 'react'; |
| 2 | +import { Link } from 'react-router-dom'; |
| 3 | +import { motion } from 'framer-motion'; |
| 4 | +import { ArrowRightIcon, FolderIcon } from '@phosphor-icons/react'; |
| 5 | + |
| 6 | +const TerracottaPostItem = ({ post, isActive, onHover = () => {} }) => { |
| 7 | + const { slug, title, date, category, series, seriesIndex, isSeries } = post; |
| 8 | + |
| 9 | + const formattedDate = new Date(date).toLocaleDateString('en-GB', { |
| 10 | + day: '2-digit', |
| 11 | + month: '2-digit', |
| 12 | + year: '2-digit', |
| 13 | + }); |
| 14 | + |
| 15 | + const categoryColor = |
| 16 | + category === 'dev' |
| 17 | + ? '#6B8E23' |
| 18 | + : category === 'series' |
| 19 | + ? '#B88532' |
| 20 | + : category === 'd&d' || category === 'dnd' |
| 21 | + ? '#9E4A2F' |
| 22 | + : category === 'gist' |
| 23 | + ? '#C96442' |
| 24 | + : category === 'feat' |
| 25 | + ? '#8A6A32' |
| 26 | + : category === 'ai' |
| 27 | + ? '#6B8E23' |
| 28 | + : '#C96442'; |
| 29 | + |
| 30 | + const categoryBg = |
| 31 | + category === 'dev' |
| 32 | + ? 'rgba(107, 142, 35, 0.18)' |
| 33 | + : category === 'series' |
| 34 | + ? 'rgba(184, 133, 50, 0.2)' |
| 35 | + : category === 'd&d' || category === 'dnd' |
| 36 | + ? 'rgba(158, 74, 47, 0.2)' |
| 37 | + : category === 'gist' |
| 38 | + ? 'rgba(201, 100, 66, 0.2)' |
| 39 | + : category === 'feat' |
| 40 | + ? 'rgba(138, 106, 50, 0.2)' |
| 41 | + : category === 'ai' |
| 42 | + ? 'rgba(107, 142, 35, 0.15)' |
| 43 | + : 'rgba(201, 100, 66, 0.18)'; |
| 44 | + |
| 45 | + return ( |
| 46 | + <motion.div |
| 47 | + initial={{ opacity: 0, x: -10 }} |
| 48 | + animate={{ opacity: 1, x: 0 }} |
| 49 | + onMouseEnter={() => onHover(post)} |
| 50 | + className="relative mr-4 md:mr-12" |
| 51 | + > |
| 52 | + <Link |
| 53 | + to={isSeries ? `/blog/series/${slug}` : `/blog/${slug}`} |
| 54 | + className="group relative flex items-center justify-between border-b border-[#1A161320] py-6 pr-20 transition-all duration-300" |
| 55 | + > |
| 56 | + <div |
| 57 | + className={`absolute left-0 top-0 h-full w-1 transition-all duration-300 ${isActive ? 'opacity-100' : 'opacity-0'}`} |
| 58 | + style={{ backgroundColor: categoryColor || '#C96442' }} |
| 59 | + /> |
| 60 | + |
| 61 | + <div className="flex flex-1 items-center gap-6 pl-4 md:pl-8 min-w-0 pr-12"> |
| 62 | + <span |
| 63 | + className={`font-mono text-[10px] tracking-widest flex-shrink-0 transition-colors duration-300 ${ |
| 64 | + isActive ? 'text-[#9E4A2F]' : 'text-[#2E2620]/50' |
| 65 | + }`} |
| 66 | + > |
| 67 | + {formattedDate} |
| 68 | + </span> |
| 69 | + |
| 70 | + <div className="flex items-center gap-3 min-w-0 flex-1"> |
| 71 | + {isSeries && ( |
| 72 | + <FolderIcon |
| 73 | + size={24} |
| 74 | + weight="fill" |
| 75 | + className="shrink-0" |
| 76 | + style={{ color: categoryColor }} |
| 77 | + /> |
| 78 | + )} |
| 79 | + <div className="flex flex-col gap-1"> |
| 80 | + <h3 |
| 81 | + className={`text-xl md:text-2xl font-playfairDisplay tracking-tight transition-all duration-300 break-words leading-tight ${ |
| 82 | + isActive |
| 83 | + ? 'translate-x-1 text-[#1A1613] italic' |
| 84 | + : 'text-[#2E2620]/60 group-hover:text-[#1A1613]' |
| 85 | + }`} |
| 86 | + > |
| 87 | + {title} |
| 88 | + </h3> |
| 89 | + |
| 90 | + {series && ( |
| 91 | + <span className="font-mono text-[9px] uppercase tracking-[0.2em] text-[#9E4A2F]/70"> |
| 92 | + {typeof series === 'object' ? series.title : series} {'//'} Part {seriesIndex} |
| 93 | + </span> |
| 94 | + )} |
| 95 | + </div> |
| 96 | + </div> |
| 97 | + </div> |
| 98 | + |
| 99 | + <div className="flex items-center gap-4 flex-shrink-0"> |
| 100 | + <span |
| 101 | + className="px-2 py-0.5 text-[9px] font-mono font-bold uppercase tracking-widest border rounded-sm transition-all duration-300" |
| 102 | + style={{ |
| 103 | + borderColor: categoryColor, |
| 104 | + backgroundColor: categoryBg, |
| 105 | + color: categoryColor, |
| 106 | + }} |
| 107 | + > |
| 108 | + {category || 'Post'} |
| 109 | + </span> |
| 110 | + |
| 111 | + <div className="w-10 flex justify-end"> |
| 112 | + <ArrowRightIcon |
| 113 | + weight="bold" |
| 114 | + size={20} |
| 115 | + className={`transition-all duration-300 ${ |
| 116 | + isActive ? 'translate-x-0 opacity-100' : '-translate-x-4 opacity-0 text-[#2E2620]/50' |
| 117 | + }`} |
| 118 | + style={{ color: isActive ? categoryColor : undefined }} |
| 119 | + /> |
| 120 | + </div> |
| 121 | + </div> |
| 122 | + </Link> |
| 123 | + </motion.div> |
| 124 | + ); |
| 125 | +}; |
| 126 | + |
| 127 | +export default TerracottaPostItem; |
0 commit comments