Skip to content

Commit 02d7be4

Browse files
committed
adding the new author feature on the existing recode blog card design
1 parent 06cac74 commit 02d7be4

5 files changed

Lines changed: 279 additions & 77 deletions

File tree

src/components/blogCarousel/blogCard.tsx

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
"use client";
2-
import * as React from "react";
3-
import { useState } from "react";
4-
import { motion } from "framer-motion";
52
import Link from "@docusaurus/Link";
63
import { Card, CardContent } from "../ui/card";
7-
import { getAuthorNames } from "../../utils/authors";
4+
import { getAuthorProfiles, getAuthorTooltip } from "../../utils/authors";
5+
6+
declare const require: any;
7+
const React = require("react");
88

99
const BlogCard = ({ type, date, title, content, imageUrl, id, authors }) => {
10-
const [isHovered, setIsHovered] = useState(false);
10+
const [isHovered, setIsHovered] = React.useState(false);
11+
const authorProfiles = getAuthorProfiles(authors || []);
1112

1213
if (!id || !type) {
1314
return <div>data not fetched properly, imageId and entryId not found</div>;
@@ -36,58 +37,63 @@ const BlogCard = ({ type, date, title, content, imageUrl, id, authors }) => {
3637
const category = getCategory(title);
3738

3839
return (
39-
<motion.div
40-
initial={{ opacity: 0, y: 40, scale: 0.95 }}
41-
animate={{ opacity: 1, y: 0, scale: 1 }}
42-
transition={{ duration: 0.6, ease: "easeOut" }}
43-
whileHover={{
44-
y: -8,
45-
scale: 1.02,
46-
transition: { duration: 0.4, ease: "easeOut" },
47-
}}
40+
<div
4841
onMouseEnter={() => setIsHovered(true)}
4942
onMouseLeave={() => setIsHovered(false)}
5043
className="relative h-full overflow-hidden transition-all duration-300"
5144
>
52-
<Link
53-
to={`/blog/${id}`}
54-
className="text-decoration-none block h-full"
55-
style={{ textDecoration: "none" }}
56-
>
57-
<div className="article-card h-full">
58-
{/* Category Badge */}
59-
<div className="card-category">{category}</div>
45+
<div className="article-card h-full">
46+
{/* Category Badge */}
47+
<div className="card-category">{category}</div>
6048

61-
{/* Card Image */}
62-
<div className="card-image">
63-
<img src={imageUrl} alt={title} />
64-
</div>
49+
{/* Card Image */}
50+
<div className="card-image">
51+
<img src={imageUrl} alt={title} />
52+
</div>
6553

66-
{/* Card Content */}
67-
<div className="card-content">
68-
<h3 className="card-title">{title}</h3>
69-
<p className="card-description">{content}</p>
54+
{/* Card Content */}
55+
<div className="card-content">
56+
<h3 className="card-title">
57+
<Link to={`/blog/${id}`} className="card-title-link">
58+
{title}
59+
</Link>
60+
</h3>
61+
<p className="card-description">{content}</p>
7062

71-
{/* Card Meta */}
72-
<div className="card-meta">
73-
<div className="card-author">
74-
<span className="author-avatar">👤</span>
75-
<span
76-
className="author-name"
77-
data-full-name={getAuthorNames(authors || [])}
78-
>
79-
{getAuthorNames(authors || [])}
80-
</span>
63+
{/* Card Meta */}
64+
<div className="card-meta">
65+
<div className="card-author">
66+
<span className="author-avatar">👤</span>
67+
<div className="author-name-group">
68+
{authorProfiles.map((author, authorIndex) => (
69+
<span key={author.id} className="author-item">
70+
{authorIndex > 0 && (
71+
<span className="author-separator">&</span>
72+
)}
73+
<Link
74+
href={author.githubUrl}
75+
className="author-name author-link"
76+
target="_blank"
77+
rel="noopener noreferrer"
78+
data-author-tooltip={getAuthorTooltip(author.id)}
79+
aria-label={`Open ${author.name} on GitHub`}
80+
>
81+
{author.name}
82+
</Link>
83+
</span>
84+
))}
8185
</div>
82-
<span className="card-read-time">5 min read</span>
8386
</div>
84-
85-
{/* Read More Button */}
86-
<div className="card-read-more">Read Article →</div>
87+
<span className="card-read-time">5 min read</span>
8788
</div>
89+
90+
{/* Read More Button */}
91+
<Link to={`/blog/${id}`} className="card-read-more">
92+
Read Article →
93+
</Link>
8894
</div>
89-
</Link>
90-
</motion.div>
95+
</div>
96+
</div>
9197
);
9298
};
9399

src/components/blogCarousel/blogCarousel.css

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@
179179
color: #a78bfa;
180180
}
181181

182+
.card-title-link {
183+
color: inherit;
184+
text-decoration: none;
185+
transition: color 0.2s ease;
186+
}
187+
188+
.card-title-link:hover {
189+
color: #6366f1;
190+
}
191+
192+
[data-theme="dark"] .card-title-link:hover {
193+
color: #a78bfa;
194+
}
195+
182196
.card-description {
183197
font-size: 14px;
184198
color: #64748b;
@@ -237,6 +251,27 @@
237251
min-width: 0;
238252
}
239253

254+
.author-name-group {
255+
display: flex;
256+
align-items: center;
257+
flex-wrap: wrap;
258+
gap: 6px;
259+
min-width: 0;
260+
}
261+
262+
.author-separator {
263+
color: #94a3b8;
264+
font-size: 12px;
265+
font-weight: 700;
266+
}
267+
268+
.author-link {
269+
display: inline-flex;
270+
align-items: center;
271+
position: relative;
272+
text-decoration: none;
273+
}
274+
240275
.author-avatar {
241276
width: 28px;
242277
height: 28px;
@@ -272,6 +307,58 @@
272307
color: #6366f1;
273308
}
274309

310+
.author-name::after {
311+
content: attr(data-author-tooltip);
312+
position: absolute;
313+
bottom: 100%;
314+
left: 50%;
315+
transform: translateX(-50%);
316+
background: rgba(0, 0, 0, 0.9);
317+
color: white;
318+
padding: 8px 12px;
319+
border-radius: 6px;
320+
font-size: 12px;
321+
white-space: pre-line;
322+
max-width: 240px;
323+
text-align: center;
324+
opacity: 0;
325+
visibility: hidden;
326+
transition: all 0.3s ease;
327+
z-index: 1000;
328+
pointer-events: none;
329+
margin-bottom: 5px;
330+
}
331+
332+
.author-name::before {
333+
content: "";
334+
position: absolute;
335+
bottom: 100%;
336+
left: 50%;
337+
transform: translateX(-50%);
338+
border: 5px solid transparent;
339+
border-top-color: rgba(0, 0, 0, 0.9);
340+
opacity: 0;
341+
visibility: hidden;
342+
transition: all 0.3s ease;
343+
z-index: 1000;
344+
pointer-events: none;
345+
}
346+
347+
[data-theme="dark"] .author-name::after {
348+
background: rgba(18, 18, 18, 0.95);
349+
color: #f7fafc;
350+
}
351+
352+
[data-theme="dark"] .author-name::before {
353+
border-top-color: rgba(18, 18, 18, 0.95);
354+
}
355+
356+
.author-name:hover::after,
357+
.author-name:hover::before {
358+
opacity: 1;
359+
visibility: visible;
360+
}
361+
275362
[data-theme="dark"] .author-name {
276363
color: #cbd5e1;
277364
}

src/pages/blogs/blogs-new.css

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,20 @@
15901590
margin-bottom: 12px;
15911591
}
15921592

1593+
1594+
.card-title-link {
1595+
color: inherit;
1596+
text-decoration: none;
1597+
transition: color 0.2s ease;
1598+
}
1599+
1600+
.card-title-link:hover {
1601+
color: #6366f1;
1602+
}
1603+
1604+
[data-theme="dark"] .card-title-link:hover {
1605+
color: #a78bfa;
1606+
}
15931607
.card-description {
15941608
font-size: 14px;
15951609
margin-bottom: 20px;
@@ -1635,6 +1649,33 @@
16351649
min-width: 0; /* Allow text to shrink */
16361650
}
16371651

1652+
.author-name-group {
1653+
display: flex;
1654+
align-items: center;
1655+
flex-wrap: wrap;
1656+
gap: 6px;
1657+
min-width: 0;
1658+
}
1659+
1660+
.author-item {
1661+
display: inline-flex;
1662+
align-items: center;
1663+
gap: 6px;
1664+
}
1665+
1666+
.author-separator {
1667+
color: #94a3b8;
1668+
font-size: 13px;
1669+
font-weight: 700;
1670+
}
1671+
1672+
.author-link {
1673+
display: inline-flex;
1674+
align-items: center;
1675+
position: relative;
1676+
text-decoration: none;
1677+
}
1678+
16381679
.author-avatar {
16391680
width: 32px;
16401681
height: 32px;
@@ -1683,7 +1724,7 @@
16831724

16841725
/* Tooltip for author names */
16851726
.author-name::after {
1686-
content: attr(data-full-name);
1727+
content: attr(data-author-tooltip);
16871728
position: absolute;
16881729
bottom: 100%;
16891730
left: 50%;
@@ -1693,7 +1734,9 @@
16931734
padding: 8px 12px;
16941735
border-radius: 6px;
16951736
font-size: 12px;
1696-
white-space: nowrap;
1737+
white-space: pre-line;
1738+
max-width: 240px;
1739+
text-align: center;
16971740
opacity: 0;
16981741
visibility: hidden;
16991742
transition: all 0.3s ease;

0 commit comments

Comments
 (0)