1
+ /* eslint-disable linebreak-style */
1
2
import React , { useState , useEffect } from 'react' ;
2
3
import Head from 'next/head' ;
3
4
import Link from 'next/link' ;
@@ -9,7 +10,7 @@ const PATH = 'pages/blog/posts';
9
10
import TextTruncate from 'react-text-truncate' ;
10
11
import generateRssFeed from './generateRssFeed' ;
11
12
import { useRouter } from 'next/router' ;
12
- import { SectionContext } from '~ /context' ;
13
+ import { SectionContext } from '../.. /context' ;
13
14
import Image from 'next/image' ;
14
15
15
16
type Author = {
@@ -197,14 +198,13 @@ export default function StaticMarkdownPage({
197
198
</ Head >
198
199
< div className = 'max-w-[1400px] mx-auto overflow-x-hidden flex flex-col items-center mt-0 sm:mt-10' >
199
200
{ recentBlog [ 0 ] && (
200
- < div className = 'relative w-full h-[500px] sm:h-[400px ] bg-black clip-bottom mt-1.5 flex flex-col items-center justify-start dark:bg-slate-700' >
201
+ < div className = 'relative w-full aspect-[16/9 ] bg-black clip-bottom mt-1.5 flex flex-col items-center justify-start dark:bg-slate-700' >
201
202
< div className = 'absolute w-full h-full dark:bg-[#282d6a]' />
202
203
< Image
203
204
src = { recentBlog [ 0 ] . frontmatter . cover }
204
- width = { 800 }
205
- height = { 450 }
206
- className = 'object-cover w-full h-full opacity-70 blur-[5px]'
207
205
alt = { recentBlog [ 0 ] . frontmatter . title }
206
+ fill
207
+ className = 'object-fill w-full h-full opacity-70 blur-[5px]'
208
208
priority
209
209
quality = { 75 }
210
210
/>
@@ -307,113 +307,125 @@ export default function StaticMarkdownPage({
307
307
308
308
return (
309
309
< section key = { blogPost . slug } >
310
- < div className = 'h-[510px] flex border rounded-lg shadow-sm hover:shadow-lg transition-all overflow-hidden dark:border-slate-500' >
311
- < Link
312
- href = { `/blog/posts/${ blogPost . slug } ` }
313
- className = 'inline-flex flex-col flex-1 w-full'
314
- >
315
- < div className = 'relative h-[160px] w-full' >
316
- < Image
317
- src = { frontmatter . cover }
318
- alt = { frontmatter . title }
319
- fill
320
- className = 'object-fill'
321
- loading = { idx < 10 ? 'eager' : 'lazy' }
322
- priority = { idx < 10 }
323
- quality = { 75 }
324
- />
310
+ < Link
311
+ href = { `/blog/posts/${ blogPost . slug } ` }
312
+ className = 'h-[600px] sm:h-[540px] flex border rounded-lg shadow-sm transition-shadow duration-300 overflow-hidden dark:border-slate-500 group flex-col flex-1 w-full'
313
+ >
314
+ < div className = 'relative w-full aspect-[16/9] overflow-hidden' >
315
+ < Image
316
+ src = { frontmatter . cover }
317
+ alt = { frontmatter . title }
318
+ fill
319
+ className = 'object-fill transition-transform duration-300 group-hover:scale-110'
320
+ loading = { idx < 10 ? 'eager' : 'lazy' }
321
+ priority = { idx < 10 }
322
+ quality = { 75 }
323
+ />
324
+ < div className = 'absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-300 pointer-events-none' />
325
+ </ div >
326
+ < div className = 'p-4 flex flex-col flex-1 justify-between min-h-0 pt-2' >
327
+ < div >
328
+ { /* Display each category as a clickable badge */ }
329
+ < div className = 'flex flex-wrap gap-2 mb-4' >
330
+ { getCategories ( frontmatter ) . map ( ( cat , index ) => (
331
+ < div
332
+ key = { index }
333
+ className = 'bg-blue-100 hover:bg-blue-200 dark:bg-slate-700 dark:text-blue-100 cursor-pointer font-semibold text-blue-800 inline-block px-3 py-1 rounded-full text-sm'
334
+ onClick = { ( e ) => {
335
+ e . preventDefault ( ) ;
336
+ e . stopPropagation ( ) ;
337
+ toggleCategory ( cat ) ;
338
+ } }
339
+ >
340
+ { cat || 'Unknown' }
341
+ </ div >
342
+ ) ) }
343
+ </ div >
344
+ < div className = 'text-lg h-[95px] font-semibold overflow-hidden transition-transform duration-300 group-hover:scale-105' >
345
+ { frontmatter . title }
346
+ </ div >
347
+ < div className = 'mt-3 text-slate-500 dark:text-slate-300 flex-1 min-h-0' >
348
+ < TextTruncate
349
+ element = 'span'
350
+ line = { 4 }
351
+ text = { frontmatter . excerpt }
352
+ />
353
+ </ div >
325
354
</ div >
326
- < div className = 'p-4 flex flex-col flex-1 justify-between' >
327
- < div >
328
- { /* Display each category as a clickable badge */ }
329
- < div className = 'flex flex-wrap gap-2 mb-4' >
330
- { getCategories ( frontmatter ) . map ( ( cat , index ) => (
355
+ < div className = 'flex flex-row items-center mt-2' >
356
+ < div className = 'flex flex-row pl-2 mr-2' >
357
+ { ( frontmatter . authors || [ ] ) . map (
358
+ ( author : Author , index : number ) => (
331
359
< div
332
360
key = { index }
333
- className = 'bg-blue-100 hover:bg-blue-200 dark:bg-slate-700 dark:text-blue-100 cursor-pointer font-semibold text-blue-800 inline-block px-3 py-1 rounded-full text-sm'
334
- onClick = { ( e ) => {
335
- e . preventDefault ( ) ;
336
- e . stopPropagation ( ) ;
337
- toggleCategory ( cat ) ;
361
+ className = { `bg-slate-50 rounded-full -ml-3 bg-cover bg-center border-2 border-white ${
362
+ frontmatter . authors . length > 2
363
+ ? 'h-8 w-8'
364
+ : 'h-11 w-11'
365
+ } `}
366
+ style = { {
367
+ backgroundImage : `url(${ author . photo } )` ,
368
+ zIndex : 10 - index ,
338
369
} }
339
- >
340
- { cat || 'Unknown' }
341
- </ div >
342
- ) ) }
343
- </ div >
344
- < div className = 'text-lg h-[80px] font-semibold' >
345
- { frontmatter . title }
346
- </ div >
347
- < div className = 'mt-3 mb-6 text-slate-500 dark:text-slate-300' >
348
- < TextTruncate
349
- element = 'span'
350
- line = { 4 }
351
- text = { frontmatter . excerpt }
352
- />
353
- </ div >
370
+ />
371
+ ) ,
372
+ ) }
354
373
</ div >
355
- < div className = 'flex flex-row items-center' >
356
- < div className = 'flex flex-row pl-2 mr-2' >
357
- { ( frontmatter . authors || [ ] ) . map (
358
- ( author : Author , index : number ) => (
359
- < div
360
- key = { index }
361
- className = { `bg-slate-50 rounded-full -ml-3 bg-cover bg-center border-2 border-white ${
362
- frontmatter . authors . length > 2
363
- ? 'h-8 w-8'
364
- : 'h-11 w-11'
365
- } `}
366
- style = { {
367
- backgroundImage : `url(${ author . photo } )` ,
368
- zIndex : 10 - index ,
369
- } }
370
- />
371
- ) ,
372
- ) }
373
- </ div >
374
- < div className = 'flex flex-col items-start' >
375
- < div className = 'text-sm font-semibold' >
376
- { frontmatter . authors . length > 2 ? (
377
- < >
378
- { frontmatter . authors
379
- . slice ( 0 , 2 )
380
- . map ( ( author : Author , index : number ) => (
381
- < span key = { author . name } >
382
- { author . name }
383
- { index === 0 && ' & ' }
384
- </ span >
385
- ) ) }
386
- { '...' }
387
- </ >
388
- ) : (
389
- frontmatter . authors . map (
390
- ( author : Author , index : number ) => (
374
+ < div className = 'flex flex-col items-start' >
375
+ < div className = 'text-sm font-semibold' >
376
+ { frontmatter . authors . length > 2 ? (
377
+ < >
378
+ { frontmatter . authors
379
+ . slice ( 0 , 2 )
380
+ . map ( ( author : Author , index : number ) => (
391
381
< span key = { author . name } >
392
382
{ author . name }
393
- { index < frontmatter . authors . length - 1 &&
394
- ' & ' }
383
+ { index === 0 && ' & ' }
395
384
</ span >
396
- ) ,
397
- )
398
- ) }
399
- </ div >
400
- < div className = 'text-slate-500 text-sm dark:text-slate-300' >
401
- { frontmatter . date && (
402
- < span >
403
- { date . toLocaleDateString ( 'en-us' , {
404
- year : 'numeric' ,
405
- month : 'long' ,
406
- day : 'numeric' ,
407
- } ) }
408
- </ span >
409
- ) } { ' ' }
410
- · { postTimeToRead } min read
411
- </ div >
385
+ ) ) }
386
+ { '...' }
387
+ </ >
388
+ ) : (
389
+ frontmatter . authors . map (
390
+ ( author : Author , index : number ) => (
391
+ < span key = { author . name } >
392
+ { author . name }
393
+ { index < frontmatter . authors . length - 1 &&
394
+ ' & ' }
395
+ </ span >
396
+ ) ,
397
+ )
398
+ ) }
399
+ </ div >
400
+ < div className = 'text-slate-500 text-sm dark:text-slate-300' >
401
+ { frontmatter . date && (
402
+ < span >
403
+ { date . toLocaleDateString ( 'en-us' , {
404
+ year : 'numeric' ,
405
+ month : 'long' ,
406
+ day : 'numeric' ,
407
+ } ) }
408
+ </ span >
409
+ ) } { ' ' }
412
410
</ div >
413
411
</ div >
414
412
</ div >
415
- </ Link >
416
- </ div >
413
+ </ div >
414
+ { /* Separator Line */ }
415
+ < div className = 'border-t border-gray-200 dark:border-slate-600 mx-4' > </ div >
416
+ { /* Read More Section */ }
417
+ < div className = 'flex w-full px-4 py-2 justify-between items-center' >
418
+ < span className = 'text-blue-600 hover:text-blue-800 font-medium text-sm flex items-center gap-1 group/readmore' >
419
+ Read More
420
+ < span className = 'transition-transform group-hover/readmore:translate-x-1 text-xs' >
421
+ →
422
+ </ span >
423
+ </ span >
424
+ < span className = 'text-slate-500 text-sm dark:text-slate-400' >
425
+ { postTimeToRead } min read
426
+ </ span >
427
+ </ div >
428
+ </ Link >
417
429
</ section >
418
430
) ;
419
431
} ) }
0 commit comments