@@ -5,6 +5,7 @@ import Spinner from '../components/Spinner'
55import Tag from '../components/Tag'
66import FavoriteButton from '../components/FavoriteButton'
77import { getUserPrefs } from '../hooks/useUserPrefs'
8+ import { getRecentBooks , getBookPrefs } from '../hooks/useBookPrefs'
89
910function SystemCard ( { system, onClick, compact } ) {
1011 const [ hovered , setHovered ] = useState ( false )
@@ -145,9 +146,62 @@ export default function LibraryView() {
145146
146147 const compact = cardSize === 'compact'
147148 const minCard = compact ? '130px' : '220px'
149+ const recentBooks = getRecentBooks ( )
148150
149151 return (
150152 < div className = "fade-in" style = { { padding : '32px 40px' , maxWidth : 1400 , width : '100%' , margin : '0 auto' , boxSizing : 'border-box' } } >
153+
154+ { /* Recently Opened */ }
155+ { recentBooks . length > 0 && (
156+ < div style = { { marginBottom : 40 } } >
157+ < h3 style = { { fontSize : 16 , color : 'var(--text-dim)' , fontWeight : 500 , marginBottom : 12 , letterSpacing : '0.05em' , textTransform : 'uppercase' } } >
158+ Recently Opened
159+ </ h3 >
160+ < div style = { { display : 'flex' , gap : 10 , flexWrap : 'wrap' } } >
161+ { recentBooks . map ( book => {
162+ const lastPage = getBookPrefs ( book . id ) . page || 1
163+ const progress = book . page_count > 0 ? Math . min ( lastPage / book . page_count , 1 ) : 0
164+ return (
165+ < div
166+ key = { book . id }
167+ onClick = { ( ) => navigate ( `/library/book/${ book . id } ?page=${ lastPage } ` ) }
168+ style = { {
169+ display : 'flex' , alignItems : 'center' , gap : 10 ,
170+ background : 'var(--bg-card)' , border : '1px solid var(--border)' ,
171+ borderRadius : 8 , padding : '8px 12px' , cursor : 'pointer' ,
172+ maxWidth : 260 , position : 'relative' , overflow : 'hidden' ,
173+ } }
174+ onMouseEnter = { e => e . currentTarget . style . background = 'var(--bg-card-hover)' }
175+ onMouseLeave = { e => e . currentTarget . style . background = 'var(--bg-card)' }
176+ >
177+ { progress > 0 && (
178+ < div style = { { position : 'absolute' , bottom : 0 , left : 0 , right : 0 , height : 2 , background : 'var(--bg-deep)' } } >
179+ < div style = { { width : `${ progress * 100 } %` , height : '100%' , background : 'var(--gold-dim)' } } />
180+ </ div >
181+ ) }
182+ < div style = { { width : 28 , height : 36 , borderRadius : 3 , overflow : 'hidden' , flexShrink : 0 , background : 'var(--bg-deep)' , display : 'flex' , alignItems : 'center' , justifyContent : 'center' } } >
183+ { book . has_thumbnail
184+ ? < img src = { mediaUrl ( `/books/${ book . id } /thumbnail` ) } alt = "" style = { { width : '100%' , height : '100%' , objectFit : 'cover' } } />
185+ : < span style = { { fontSize : 14 , color : 'var(--text-muted)' } } > 📄</ span >
186+ }
187+ </ div >
188+ < div style = { { minWidth : 0 } } >
189+ < div style = { { fontSize : 13 , fontWeight : 500 , overflow : 'hidden' , textOverflow : 'ellipsis' , whiteSpace : 'nowrap' , maxWidth : 180 } } >
190+ { book . title }
191+ </ div >
192+ { progress > 0 && (
193+ < div style = { { fontSize : 11 , color : 'var(--gold-dim)' , marginTop : 2 } } >
194+ p. { lastPage } { book . page_count > 0 ? ` / ${ book . page_count } ` : '' }
195+ </ div >
196+ ) }
197+ </ div >
198+ </ div >
199+ )
200+ } ) }
201+ </ div >
202+ </ div >
203+ ) }
204+
151205 < div style = { { marginBottom : 32 } } >
152206 < h2 style = { { fontSize : 28 , marginBottom : 8 } } > Your Collection</ h2 >
153207 < p style = { { color : 'var(--text-dim)' , fontSize : 17 , fontFamily : 'Alegreya, serif' , fontStyle : 'italic' } } >
0 commit comments