@@ -63,7 +63,7 @@ const StatCard = ({ title, value, icon: Icon, colorClass, bgClass, delay }) => (
6363 </ motion . div >
6464) ;
6565
66- const DetailCard = ( { title, icon : Icon , children, bgClass, delay } ) => (
66+ const DetailCard = ( { title, icon : Icon , children, bgClass, delay, footerLink , footerLabel } ) => (
6767 < motion . div
6868 initial = { { opacity : 0 , y : 20 } }
6969 animate = { { opacity : 1 , y : 0 } }
@@ -82,6 +82,15 @@ const DetailCard = ({ title, icon: Icon, children, bgClass, delay }) => (
8282 < div className = "flex-grow font-inter relative z-10" >
8383 { children }
8484 </ div >
85+ { footerLink && footerLabel && (
86+ < div className = "mt-6 pt-4 border-t border-white/5 relative z-10" >
87+ < Link to = { footerLink } >
88+ < button className = "w-full py-3 rounded-xl bg-[#1a1a1a] hover:bg-[#252525] text-white/70 hover:text-white text-[10px] font-bold uppercase tracking-widest transition-colors font-inter border border-white/10 hover:border-white/20 flex items-center justify-center gap-2" >
89+ { footerLabel } < ArrowUpRight size = { 14 } weight = "bold" />
90+ </ button >
91+ </ Link >
92+ </ div >
93+ ) }
8594 </ motion . div >
8695) ;
8796
@@ -200,10 +209,22 @@ const DashboardPage = () => {
200209 const logCategories = [ 'article' , 'book' , 'event' , 'food' , 'game' , 'movie' , 'music' , 'reading' , 'series' , 'tools' , 'video' , 'websites' ] ;
201210 const logsData = { } ;
202211
203- // Quick fetch for logs (mocking counts for simplicity/speed as per original logic)
204- for ( const cat of logCategories ) {
205- logsData [ cat ] = { length : Math . floor ( Math . random ( ) * 20 ) + 1 } ;
206- }
212+ // Fetch actual log counts
213+ await Promise . all ( logCategories . map ( async ( cat ) => {
214+ try {
215+ const res = await fetch ( `/logs/${ cat } /${ cat } .piml` ) ;
216+ if ( res . ok ) {
217+ const text = await res . text ( ) ;
218+ const parsed = piml . parse ( text ) ;
219+ logsData [ cat ] = { length : ( parsed . items || parsed . logs || [ ] ) . length } ;
220+ } else {
221+ logsData [ cat ] = { length : 0 } ;
222+ }
223+ } catch ( e ) {
224+ console . error ( `Error fetching logs for ${ cat } :` , e ) ;
225+ logsData [ cat ] = { length : 0 } ;
226+ }
227+ } ) ) ;
207228
208229 setData ( {
209230 posts : postsData ,
@@ -244,7 +265,8 @@ const DashboardPage = () => {
244265
245266 // Derived Distribution Data
246267 const postsByCategory = data . posts . reduce ( ( acc , post ) => {
247- acc [ post . category ] = ( acc [ post . category ] || 0 ) + 1 ;
268+ const cat = post . category || 'Other' ;
269+ acc [ cat ] = ( acc [ cat ] || 0 ) + 1 ;
248270 return acc ;
249271 } , { } ) ;
250272
@@ -282,7 +304,9 @@ const DashboardPage = () => {
282304 < div className = "w-1.5 h-1.5 rounded-full bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]" />
283305 < span className = "text-xs font-medium text-white/70 tracking-wide font-inter" > v{ version } Stable</ span >
284306 </ div >
285- < DashboardButton icon = { Wallet } primary > System Online</ DashboardButton >
307+ < Link to = "/about/skills" >
308+ < DashboardButton icon = { Info } primary > About</ DashboardButton >
309+ </ Link >
286310 </ div >
287311 </ div >
288312 </ div >
@@ -337,24 +361,45 @@ const DashboardPage = () => {
337361
338362 { /* DETAIL BREAKDOWN */ }
339363 < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6" >
340- < DetailCard title = "Content Distribution" icon = { Newspaper } bgClass = "bg-blue-500/5" delay = { 0.5 } >
364+ < DetailCard
365+ title = "Content Distribution"
366+ icon = { Newspaper }
367+ bgClass = "bg-blue-500/5"
368+ delay = { 0.5 }
369+ footerLink = "/blog"
370+ footerLabel = "View Blog"
371+ >
341372 < div className = "space-y-1" >
342373 { Object . entries ( postsByCategory ) . slice ( 0 , 5 ) . map ( ( [ cat , count ] ) => (
343374 < ProgressBar key = { cat } label = { cat } value = { count } max = { totalPosts } color = "bg-blue-500" />
344375 ) ) }
345376 </ div >
346377 </ DetailCard >
347378
348- < DetailCard title = "App Ecosystem" icon = { AppWindow } bgClass = "bg-purple-500/5" delay = { 0.6 } >
379+ < DetailCard
380+ title = "App Ecosystem"
381+ icon = { AppWindow }
382+ bgClass = "bg-purple-500/5"
383+ delay = { 0.6 }
384+ footerLink = "/apps"
385+ footerLabel = "Explore Apps"
386+ >
349387 < div className = "space-y-1" >
350388 { Object . keys ( data . apps ) . map ( ( cat ) => (
351389 < ProgressBar key = { cat } label = { cat } value = { data . apps [ cat ] . apps . length } max = { totalApps } color = "bg-purple-500" />
352390 ) ) }
353391 </ div >
354392 </ DetailCard >
355393
356- < DetailCard title = "Project Health" icon = { Kanban } bgClass = "bg-orange-500/5" delay = { 0.7 } >
357- < div className = "flex gap-4 mb-8" >
394+ < DetailCard
395+ title = "Project Health"
396+ icon = { Kanban }
397+ bgClass = "bg-orange-500/5"
398+ delay = { 0.7 }
399+ footerLink = "/projects"
400+ footerLabel = "View All Projects"
401+ >
402+ < div className = "flex gap-4 mb-2" >
358403 < div className = "flex-1 bg-[#1a1a1a] p-4 rounded-2xl text-center border border-white/5" >
359404 < div className = "text-2xl font-normal text-white font-inter" > { projectStatus . active } </ div >
360405 < div className = "text-[10px] uppercase text-white/50 tracking-widest font-inter" > Active</ div >
@@ -364,11 +409,6 @@ const DashboardPage = () => {
364409 < div className = "text-[10px] uppercase text-white/50 tracking-widest font-inter" > Archived</ div >
365410 </ div >
366411 </ div >
367- < Link to = "/projects" >
368- < button className = "w-full py-3 rounded-xl bg-[#1a1a1a] hover:bg-[#252525] text-white/70 hover:text-white text-xs font-medium uppercase tracking-widest transition-colors font-inter border border-white/10 hover:border-white/20" >
369- View All Projects
370- </ button >
371- </ Link >
372412 </ DetailCard >
373413 </ div >
374414
0 commit comments