Skip to content

Commit 70aa405

Browse files
committed
refactor: blog viewer.
1 parent 48e2a4b commit 70aa405

File tree

7 files changed

+370
-242
lines changed

7 files changed

+370
-242
lines changed

public/roadmap/roadmap.piml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,14 @@
6060
(created_at) 2025-11-28T18:00:00+03:00
6161
(due_date) 2025-11-30T00:00:00+03:00
6262
(notes) Futuristic Cyan Theme.
63+
64+
> (issues)
65+
(id) FEZ-6
66+
(title) Refactor Blogpost Page
67+
(description) Better styles & UI/UX for blog related pages and components.
68+
(category) UI/UX
69+
(status) Completed
70+
(priority) High
71+
(created_at) 2025-11-28T18:00:00+03:00
72+
(due_date) 2025-11-30T00:00:00+03:00
73+
(notes) Futuristic Cyan Theme.

public/timeline/timeline.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
[
2+
{
3+
"date": "2025-11-29",
4+
"title": "Blog & Series Styling Overhaul",
5+
"description": "Applied the new futuristic design language to Blog Post and Series pages, including enhanced typography, sticky metadata, and improved code block styling.",
6+
"type": "refactor",
7+
"icon": "SparkleIcon",
8+
"link": "/#/blog"
9+
},
210
{
311
"date": "2025-11-29",
412
"title": "Projects Overhaul Refactor",
Lines changed: 104 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
11
import React from 'react';
2-
import { Link } from 'react-router-dom';
2+
import {Link} from 'react-router-dom';
33
import Label from '../Label';
4+
import {ArrowUp, ArrowDown} from '@phosphor-icons/react';
5+
6+
const getCategoryStyles = (category) => {
7+
switch (category) {
8+
case 'dev':
9+
return 'text-blue-300 bg-blue-900/20 border border-blue-900/50 hover:bg-blue-900/40';
10+
case 'series':
11+
return 'text-rose-300 bg-rose-900/20 border border-rose-900/50 hover:bg-rose-900/40';
12+
case 'd&d':
13+
case 'dnd':
14+
return 'text-pink-300 bg-pink-900/20 border border-pink-900/50 hover:bg-pink-900/40';
15+
case 'gist':
16+
return 'text-amber-300 bg-amber-900/20 border border-amber-900/50 hover:bg-amber-900/40';
17+
case 'feat':
18+
return 'text-purple-300 bg-purple-900/20 border border-purple-900/50 hover:bg-purple-900/40';
19+
case 'rant':
20+
return 'text-emerald-300 bg-emerald-900/20 border border-emerald-900/50 hover:bg-emerald-900/40';
21+
default:
22+
return 'text-cyan-300 bg-cyan-900/20 border border-cyan-900/50 hover:bg-cyan-900/40';
23+
}
24+
};
425

526
const PostMetadata = ({
6-
metadata,
7-
readingProgress,
8-
isAtTop,
9-
overrideDate,
10-
updatedDate,
11-
seriesPosts,
12-
estimatedReadingTime,
13-
}) => {
27+
metadata,
28+
readingProgress,
29+
isAtTop,
30+
overrideDate,
31+
updatedDate,
32+
seriesPosts,
33+
estimatedReadingTime,
34+
}) => {
1435
if (!metadata) {
1536
return null;
1637
}
@@ -21,56 +42,50 @@ const PostMetadata = ({
2142
? new Date(metadata.date).toLocaleDateString()
2243
: 'Invalid Date');
2344

24-
const categoryBadgeColorStyle = {
25-
backgroundColor:
26-
metadata.category === 'dev'
27-
? 'var(--color-dev-badge)'
28-
: metadata.category === 'series'
29-
? 'var(--color-series-badge)'
30-
: metadata.category === 'd&d'
31-
? 'var(--color-dnd-badge)'
32-
: metadata.category === 'gist'
33-
? 'var(--color-gist-badge)'
34-
: metadata.category === 'feat'
35-
? 'var(--color-feat-badge)'
36-
: 'var(--color-rant-badge)',
37-
};
38-
39-
const categoryBadgeFontColorStyle =
40-
metadata.category === 'gist' || metadata.category === 'gist'
41-
? 'text-black'
42-
: 'text-white';
4345
const handleButtonClick = () => {
4446
if (isAtTop) {
4547
window.scrollTo({
4648
top: document.documentElement.scrollHeight,
4749
behavior: 'smooth',
4850
});
4951
} else {
50-
window.scrollTo({ top: 0, behavior: 'smooth' });
52+
window.scrollTo({top: 0, behavior: 'smooth'});
5153
}
5254
};
5355

5456
return (
55-
<aside className="sticky top-24">
56-
<div className="p-6 bg-gray-800/50 rounded-lg border border-gray-700/50">
57-
<h3 className="text-lg font-semibold text-gray-100 mb-4 border-b pb-2 border-gray-500">
58-
About Post
57+
58+
<aside className="w-full">
59+
<div
60+
className="p-6 bg-gray-900/80 backdrop-blur-md rounded-xl border border-gray-800 shadow-lg relative overflow-hidden group">
61+
{/* Decor element */}
62+
<div className="absolute top-0 right-0 p-3 opacity-50">
63+
<div className="flex gap-1">
64+
<div className="w-1 h-1 bg-cyan-500 rounded-full"></div>
65+
<div className="w-1 h-1 bg-gray-600 rounded-full"></div>
66+
</div>
67+
</div>
68+
69+
<h3
70+
className="text-sm font-mono font-bold text-cyan-400 mb-6 border-b border-gray-800 pb-3 uppercase tracking-widest flex items-center gap-2">
71+
<span className="w-2 h-2 bg-cyan-500 rounded-sm"></span>
72+
Post Data
5973
</h3>
60-
<div className="space-y-4">
74+
75+
<div className="space-y-6">
6176
<div>
62-
<Label>Original Title</Label>
63-
<p className="text-gray-300 ml-1 mt-1 ">{metadata.title}</p>
77+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Original Title</Label>
78+
<p className="text-gray-200 mt-1 font-medium">{metadata.title}</p>
6479
</div>
6580
{metadata.authors && metadata.authors.length > 0 && (
6681
<div>
67-
<Label>Author(s)</Label>
68-
<p className="ml-1 mt-1">
82+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Author(s)</Label>
83+
<p className="mt-1">
6984
{metadata.authors.map((author, index) => (
7085
<React.Fragment key={author}>
71-
<span className="text-rose-400">{author}</span>
86+
<span className="text-cyan-300 font-mono text-sm">{author}</span>
7287
{index < metadata.authors.length - 1 && (
73-
<span className="text-gray-300"> & </span>
88+
<span className="text-gray-500"> & </span>
7489
)}
7590
</React.Fragment>
7691
))}
@@ -79,43 +94,44 @@ const PostMetadata = ({
7994
)}
8095
{metadata.category && (
8196
<div>
82-
<Label>Category</Label>
83-
<span
84-
className={`ml-1 px-2 py-1 font-arvo text-xs ${categoryBadgeFontColorStyle} rounded-md w-16 text-center`}
85-
style={categoryBadgeColorStyle}
86-
>
87-
{metadata.category}
88-
</span>
97+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Category</Label>
98+
<div className="mt-1">
99+
<span
100+
className={`inline-block px-2 py-1 font-mono text-xs rounded uppercase ${getCategoryStyles(metadata.category)}`}
101+
>
102+
{metadata.category}
103+
</span>
104+
</div>
89105
</div>
90106
)}
91107
<div>
92-
<Label>Date</Label>
93-
<p className="text-gray-300 ml-1 mt-1">{displayDate}</p>
108+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Date</Label>
109+
<p className="text-gray-300 mt-1 font-mono text-sm">{displayDate}</p>
94110
</div>
95111
{updatedDate && (
96112
<div>
97-
<Label>Updated</Label>
98-
<p className="text-gray-300 ml-1 mt-1">{updatedDate}</p>
113+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Updated</Label>
114+
<p className="text-gray-300 mt-1 font-mono text-sm">{updatedDate}</p>
99115
</div>
100116
)}
101117
{estimatedReadingTime > 0 && (
102118
<div>
103-
<Label>Reading Time</Label>
104-
<p className="text-gray-300 ml-1 mt-1">
119+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Reading Time</Label>
120+
<p className="text-gray-300 mt-1 font-mono text-sm">
105121
{estimatedReadingTime} min read
106122
</p>
107123
</div>
108124
)}
109125
{metadata.tags && (
110126
<div>
111-
<Label>Tags</Label>
127+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Tags</Label>
112128
<div className="flex flex-wrap gap-2 mt-2">
113129
{metadata.tags.map((tag) => (
114130
<span
115131
key={tag}
116-
className="bg-primary-400/10 text-primary-400 text-xs font-medium px-2.5 py-1 rounded-full"
132+
className="bg-cyan-900/20 text-cyan-300 border border-cyan-900/50 text-xs font-mono px-2 py-1 rounded hover:bg-cyan-900/40 transition-colors cursor-default"
117133
>
118-
{tag}
134+
#{tag}
119135
</span>
120136
))}
121137
</div>
@@ -124,22 +140,25 @@ const PostMetadata = ({
124140

125141
{metadata.series && seriesPosts && seriesPosts.length > 0 && (
126142
<>
127-
<div>
128-
<Label>Series</Label>
129-
<p className="text-gray-300 ml-1 mt-1">
143+
<div className="pt-4 border-t border-gray-800">
144+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Series</Label>
145+
<p className="text-cyan-400 mt-1 font-bold">
130146
{metadata.series.title}
131147
</p>
132148
</div>
133149
<div>
134-
<Label>Episodes</Label>
135-
<ul className="list-disc list-inside ml-4 mt-2 text-gray-300">
150+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono">Episodes</Label>
151+
<ul className="space-y-2 mt-2">
136152
{seriesPosts.map((postInSeries) => {
137153
const episodeLink = `/blog/series/${metadata.series.slug}/${postInSeries.slug}`;
154+
const isActive = postInSeries.slug === metadata.slug;
138155
return (
139-
<li key={postInSeries.slug}>
156+
<li key={postInSeries.slug} className="flex items-start gap-2 text-sm">
157+
<span
158+
className={`mt-1.5 w-1.5 h-1.5 rounded-full flex-shrink-0 ${isActive ? 'bg-cyan-500 animate-pulse' : 'bg-gray-700'}`}></span>
140159
<Link
141160
to={episodeLink}
142-
className={`hover:text-primary-400 ${postInSeries.slug === metadata.slug ? 'font-semibold text-primary-400' : ''}`}
161+
className={`transition-colors ${isActive ? 'text-cyan-400 font-bold' : 'text-gray-400 hover:text-cyan-300'}`}
143162
>
144163
{postInSeries.title}
145164
</Link>
@@ -151,27 +170,39 @@ const PostMetadata = ({
151170
</>
152171
)}
153172
</div>
154-
<div className="mt-6">
155-
<Label className="mb-1">Reading Progress</Label>
156-
<div className="w-full bg-gray-700 rounded-full h-2.5 mt-2">
173+
174+
<div className="mt-8 pt-6 border-t border-gray-800">
175+
<Label className="text-gray-500 text-xs uppercase tracking-wider font-mono mb-2 block">Reading
176+
Progress</Label>
177+
<div className="w-full bg-gray-800 rounded-full h-1.5 overflow-hidden mt-2">
157178
<div
158-
className="bg-primary-500 h-2.5 rounded-full"
159-
style={{ width: `${readingProgress}%` }}
179+
className="bg-cyan-500 h-full transition-all duration-300 ease-out shadow-[0_0_10px_rgba(6,182,212,0.5)]"
180+
style={{width: `${readingProgress}%`}}
160181
></div>
161182
</div>
162183
</div>
163-
<div className="mt-6 text-center">
184+
185+
<div className="mt-6">
164186
<button
165187
onClick={handleButtonClick}
166-
className="text-primary-400 hover:text-primary-500 transition-colors text-sm font-medium flex items-center justify-center w-full py-2 rounded-md bg-gray-700/50 hover:bg-gray-700"
188+
className="group flex items-center justify-center w-full py-3 rounded-lg bg-gray-800 hover:bg-gray-700 text-gray-300 hover:text-cyan-400 transition-all duration-300 border border-transparent hover:border-cyan-500/30 text-sm font-mono uppercase tracking-wider"
167189
>
168-
<span className="mr-1">{isAtTop ? '↓' : '↑'}</span>{' '}
169-
{isAtTop ? 'To the bottom' : 'To the top'}
190+
{isAtTop ? (
191+
<>
192+
<ArrowDown className="mr-2 group-hover:translate-y-1 transition-transform" size={16}/>
193+
To Bottom
194+
</>
195+
) : (
196+
<>
197+
<ArrowUp className="mr-2 group-hover:-translate-y-1 transition-transform" size={16}/>
198+
To Top
199+
</>
200+
)}
170201
</button>
171202
</div>
172203
</div>
173204
</aside>
174205
);
175206
};
176207

177-
export default PostMetadata;
208+
export default PostMetadata;

0 commit comments

Comments
 (0)