11import React from 'react' ;
2- import { Link } from 'react-router-dom' ;
2+ import { Link } from 'react-router-dom' ;
33import colors from '../config/colors' ;
44import {
5- BookOpen ,
6- FilmStrip ,
7- GameController ,
8- Article ,
9- MusicNote ,
10- Television ,
11- ForkKnife ,
12- Globe ,
13- Star ,
14- Wrench ,
5+ BookOpenIcon ,
6+ FilmStripIcon ,
7+ GameControllerIcon ,
8+ ArticleIcon ,
9+ MusicNoteIcon ,
10+ TelevisionIcon ,
11+ ForkKnifeIcon ,
12+ GlobeIcon ,
13+ StarIcon ,
14+ WrenchIcon ,
15+ CalendarBlankIcon ,
1516} from '@phosphor-icons/react' ;
1617
1718const categoryIcons = {
18- Book : < BookOpen /> ,
19- Movie : < FilmStrip /> ,
20- Game : < GameController /> ,
21- Article : < Article /> ,
22- Music : < MusicNote /> ,
23- Series : < Television /> ,
24- Food : < ForkKnife /> ,
25- Websites : < Globe /> ,
26- Tools : < Wrench /> ,
19+ Book : < BookOpenIcon weight = "duotone" /> ,
20+ Movie : < FilmStripIcon weight = "duotone" /> ,
21+ Game : < GameControllerIcon weight = "duotone" /> ,
22+ Article : < ArticleIcon weight = "duotone" /> ,
23+ Music : < MusicNoteIcon weight = "duotone" /> ,
24+ Series : < TelevisionIcon weight = "duotone" /> ,
25+ Food : < ForkKnifeIcon weight = "duotone" /> ,
26+ Websites : < GlobeIcon weight = "duotone" /> ,
27+ Tools : < WrenchIcon weight = "duotone" /> ,
2728} ;
2829
29- const categoryStyles = {
30- Book : {
31- backgroundColor : colors [ 'book-alpha-10' ] ,
32- borderColor : colors [ 'book-alpha-50' ] ,
33- textColor : colors . book ,
34- } ,
35- Movie : {
36- backgroundColor : colors [ 'movie-alpha-10' ] ,
37- borderColor : colors [ 'movie-alpha-50' ] ,
38- textColor : colors . movie ,
39- } ,
40- Game : {
41- backgroundColor : colors [ 'game-alpha-10' ] ,
42- borderColor : colors [ 'game-alpha-50' ] ,
43- textColor : colors . game ,
44- } ,
45- Article : {
46- backgroundColor : colors [ 'article-alpha-10' ] ,
47- borderColor : colors [ 'article-alpha-50' ] ,
48- textColor : colors . article ,
49- } ,
50- Music : {
51- backgroundColor : colors [ 'music-alpha-10' ] ,
52- borderColor : colors [ 'music-alpha-50' ] ,
53- textColor : colors . music ,
54- } ,
55- Series : {
56- backgroundColor : colors [ 'series-alpha-10' ] ,
57- borderColor : colors [ 'series-alpha-50' ] ,
58- textColor : colors . series ,
59- } ,
60- Food : {
61- backgroundColor : colors [ 'food-alpha-10' ] ,
62- borderColor : colors [ 'food-alpha-50' ] ,
63- textColor : colors . food ,
64- } ,
65- Websites : {
66- backgroundColor : colors [ 'websites-alpha-10' ] ,
67- borderColor : colors [ 'websites-alpha-50' ] ,
68- textColor : colors . websites ,
69- } ,
70- Tools : {
71- backgroundColor : colors [ 'tools-alpha-10' ] ,
72- borderColor : colors [ 'tools-alpha-50' ] ,
73- textColor : colors . tools ,
74- } ,
30+ const categoryColors = {
31+ Book : colors . book ,
32+ Movie : colors . movie ,
33+ Game : colors . game ,
34+ Article : colors . article ,
35+ Music : colors . music ,
36+ Series : colors . series ,
37+ Food : colors . food ,
38+ Websites : colors . websites ,
39+ Tools : colors . tools ,
7540} ;
7641
77- const LogCard = ( { log, index, totalLogs } ) => {
42+ const LogCard = ( { log, index, totalLogs} ) => {
7843 const {
7944 title,
8045 category,
@@ -89,94 +54,92 @@ const LogCard = ({ log, index, totalLogs }) => {
8954 rating,
9055 slug,
9156 updated,
57+ album, // Added album
58+ releaseDate, // Added releaseDate
9259 } = log ;
9360
94- const cardStyle = categoryStyles [ category ] || { } ;
95- const detailTextColor = colors [ category . toLowerCase ( ) + '-light' ] ;
61+ const accentColor = categoryColors [ category ] || colors . primary [ 400 ] ;
62+ const Icon = categoryIcons [ category ] || < ArticleIcon /> ;
9663
9764 const renderStars = ( rating ) => {
9865 const stars = [ ] ;
99- const starColor = cardStyle . textColor ;
100- const emptyStarColor = colors [ category . toLowerCase ( ) + '-alpha-50' ] ;
101-
10266 for ( let i = 0 ; i < 5 ; i ++ ) {
103- if ( i < rating ) {
104- stars . push (
105- < Star key = { i } size = { 16 } weight = "fill" style = { { color : starColor } } /> ,
106- ) ;
107- } else {
108- stars . push (
109- < Star
110- key = { i }
111- size = { 16 }
112- weight = "fill"
113- style = { { color : emptyStarColor } }
114- /> ,
115- ) ;
116- }
67+ stars . push (
68+ < StarIcon
69+ key = { i }
70+ size = { 14 }
71+ weight = "fill"
72+ className = { i < rating ? '' : 'opacity-30' }
73+ style = { { color : i < rating ? accentColor : '#9ca3af' } }
74+ />
75+ ) ;
11776 }
118- return < div className = "flex ml-1 mt-1 " > { stars } </ div > ;
77+ return < div className = "flex gap-0.5 " > { stars } </ div > ;
11978 } ;
79+
80+ // Metadata helper to avoid rendering empty fields
81+ const MetadataItem = ( { label, value} ) => (
82+ value ? (
83+ < div
84+ className = "flex items-center gap-1 text-xs text-gray-400 bg-gray-800/50 px-2 py-1 rounded-md border border-gray-700/50" >
85+ < span className = "font-semibold text-gray-500" > { label } :</ span >
86+ < span className = "truncate max-w-[150px]" > { value } </ span >
87+ </ div >
88+ ) : null
89+ ) ;
90+
12091 return (
121- < Link to = { `/logs/${ slug } ` } className = "block" >
92+ < Link to = { `/logs/${ slug } ` } className = "block h-full group " >
12293 < div
123- className = "group bg-transparent border rounded-lg shadow-lg p-6 flex flex-col justify-between relative transform transition-all duration-300 ease-in-out hover:scale-105 hover:shadow-2xl overflow-hidden h-full "
124- style = { cardStyle }
94+ className = "relative h-full border border-gray-800 rounded-xl overflow-hidden transition-all duration-300 hover:-translate-y-1 hover:shadow-xl hover:border-gray-700 flex flex-col "
95+ style = { { backgroundColor : ` ${ accentColor } 30` } }
12596 >
97+ { /* Left Border Accent */ }
12698 < div
127- className = "absolute top-3 right-3 text-lg font-semibold px-2 py-1 rounded-md border overflow-hidden whitespace-nowrap"
128- style = { {
129- backgroundColor : 'rgba(0, 0, 0, 0.2)' ,
130- color : cardStyle . textColor ,
131- borderColor : cardStyle . borderColor ,
132- } }
133- >
134- #{ totalLogs - index }
135- </ div >
136- < div
137- className = "absolute top-0 left-0 w-full h-full opacity-0 group-hover:opacity-10 transition-opacity duration-500 ease-in-out"
138- style = { {
139- backgroundImage :
140- 'radial-gradient(circle, white 1px, transparent 1px)' ,
141- backgroundSize : '10px 10px' ,
142- } }
143- > </ div >
144- < div >
145- < div className = "flex items-center justify-between mb-4 pr-10" >
146- < div className = "flex items-center" >
147- < div className = "text-2xl mr-4" style = { { color : detailTextColor } } >
148- { categoryIcons [ category ] }
149- </ div >
150- < h2
151- className = { `text-xl font-normal` }
152- style = { { color : cardStyle . textColor } }
153- >
154- { title }
155- </ h2 >
99+ className = "absolute top-0 bottom-0 left-0 w-1 transition-all duration-300 group-hover:w-1.5"
100+ style = { { backgroundColor : accentColor } }
101+ />
102+ < div className = "p-5 flex flex-col h-full ml-1" > { /* ml-1 to account for border */ }
103+ { /* Header: Icon, Index */ }
104+ < div className = "flex justify-between items-start mb-3" >
105+ < div className = "p-2 rounded-lg bg-gray-800/80 text-white" style = { { color : accentColor } } >
106+ < span className = "text-2xl" > { Icon } </ span >
156107 </ div >
108+ < span className = "text-xs font-mono text-gray-600 group-hover:text-gray-400 transition-colors" >
109+ #{ totalLogs - index }
110+ </ span >
157111 </ div >
158- < div className = "text-sm mb-4" style = { { color : detailTextColor } } >
159- { author && < div > Author: { author } </ div > }
160- { director && < div > Director: { director } </ div > }
161- { platform && < div > Platform: { platform } </ div > }
162- { source && < div > Source: { source } </ div > }
163- { artist && < div > Artist: { artist } </ div > }
164- { year && < div > Year: { year } </ div > }
165- { creator && < div > Creator: { creator } </ div > }
166- </ div >
167- </ div >
168- < div className = "flex items-center justify-between" >
169- < div className = "flex items-center" >
170- < div className = "text-yellow-400" > { renderStars ( rating ) } </ div >
171- < div className = "text-gray-400 ml-2" > ({ rating } /5)</ div >
112+ { /* Title */ }
113+ < h3 className = "text-lg font-bold text-gray-100 mb-2 leading-snug group-hover:text-white transition-colors" >
114+ { title }
115+ </ h3 >
116+ { /* Metadata Grid */ }
117+ < div className = "flex flex-wrap gap-2 mb-4" >
118+ < MetadataItem label = "By" value = { author || artist || creator || director } />
119+ < MetadataItem label = "On" value = { platform || source } />
120+ < MetadataItem label = "Year" value = { year || ( releaseDate ? releaseDate . split ( '-' ) [ 0 ] : null ) } />
121+ { album && < MetadataItem label = "Album" value = { album } /> }
172122 </ div >
173- < div >
174- { updated && (
175- < div className = "text-xs text-rose-300 text-right" >
176- (U): { updated }
123+
124+ { /* Spacer */ }
125+ < div className = "flex-grow" />
126+
127+ { /* Footer: Rating & Date */ }
128+ < div className = "flex items-end justify-between mt-4 pt-4 border-t border-gray-800" >
129+ < div className = "flex flex-col gap-1" >
130+ { renderStars ( rating ) }
131+ { rating > 0 && < span className = "text-xs text-gray-500 font-mono" > ({ rating } /5)</ span > }
132+ </ div >
133+
134+ < div className = "text-right flex flex-col items-end" >
135+ { updated && (
136+ < span className = "text-[10px] text-rose-400 font-mono mb-0.5" > Updated</ span >
137+ ) }
138+ < div className = "flex items-center gap-1 text-xs text-gray-500 font-mono" >
139+ < CalendarBlankIcon size = { 12 } />
140+ { date }
177141 </ div >
178- ) }
179- < div className = "text-sm text-blue-400 text-right" > { date } </ div >
142+ </ div >
180143 </ div >
181144 </ div >
182145 </ div >
0 commit comments