Skip to content

Commit 7a9a214

Browse files
committed
feat: author cards.
1 parent e901324 commit 7a9a214

File tree

4 files changed

+214
-5
lines changed

4 files changed

+214
-5
lines changed

public/stories/books.piml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
(authors)
22
> (author)
3-
(name) fezcode
3+
(name) Samil
4+
(alias) fezcode
45
(website) https://fezcode.com
6+
(image) https://avatars.githubusercontent.com/u/49845895?v=4
7+
> (author)
8+
(name) Sabri
9+
(alias) TheLastRoadRunner
10+
(website) https://github.com/TheLastRoadRunner
11+
(image) https://avatars.githubusercontent.com/u/99679216?v=4
512

613
(books)
714
> (book)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react';
2+
import { Link } from 'react-router-dom';
3+
4+
const DndAuthorCard = ({ authorName, authorWebsite, authorImage, authorAlias, booksWritten }) => {
5+
return (
6+
<div className="dnd-author-card">
7+
<img src={authorImage} alt={authorName} className="dnd-author-image" />
8+
<h3 className="dnd-author-name">{authorName}</h3>
9+
{authorAlias && (
10+
<p className="dnd-author-alias">
11+
<span className="dnd-author-label">Alias:</span> {authorAlias}
12+
</p>
13+
)}
14+
{authorWebsite && (
15+
<p className="dnd-author-website">
16+
<a href={authorWebsite} target="_blank" rel="noopener noreferrer">
17+
Website
18+
</a>
19+
</p>
20+
)}
21+
{booksWritten && booksWritten.length > 0 && (
22+
<div className="dnd-author-books">
23+
<h4>Books:</h4>
24+
<hr className="dnd-author-books-separator" />
25+
<ul>
26+
{booksWritten.map((book, index) => (
27+
<li key={index}>
28+
<Link to={`/stories/books/${book.bookId}`}>{book.bookTitle}</Link>
29+
</li>
30+
))}
31+
</ul>
32+
</div>
33+
)}
34+
</div>
35+
);
36+
};
37+
38+
export default DndAuthorCard;

src/pages/dnd/DndAuthorsPage.js

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import React from 'react';
1+
import React, { useState, useEffect, useContext } from 'react';
22
import { motion } from 'framer-motion';
33
import '../../styles/dnd.css';
44
import useSeo from "../../hooks/useSeo";
5+
import piml from 'piml'; // Import piml
6+
import { DndContext } from '../../context/DndContext'; // Import DndContext
7+
import DndAuthorCard from '../../components/dnd/DndAuthorCard'; // Import DndAuthorCard
8+
import { parseWallpaperName } from '../../utils/dndUtils'; // Import parseWallpaperName
9+
import dndWallpapers from '../../utils/dndWallpapers'; // Import dndWallpapers
510

611
const pageVariants = {
712
initial: {
@@ -22,6 +27,11 @@ const pageTransition = {
2227
};
2328

2429
function DndAuthorsPage() {
30+
const { setBreadcrumbs, setBgImageName } = useContext(DndContext);
31+
const [authors, setAuthors] = useState([]);
32+
const [books, setBooks] = useState([]);
33+
const [bgImage, setBgImage] = useState(''); // State for background image
34+
2535
useSeo({
2636
title: 'Authors | From Serfs and Frauds',
2737
description: 'Meet the authors behind the Dungeons & Dragons campaign, From Serfs and Frauds.',
@@ -35,6 +45,50 @@ function DndAuthorsPage() {
3545
twitterImage: 'https://fezcode.github.io/logo512.png'
3646
});
3747

48+
useEffect(() => {
49+
setBreadcrumbs([
50+
{ label: 'S&F', path: '/stories' },
51+
{ label: 'Authors' },
52+
]);
53+
54+
const images = dndWallpapers;
55+
const randomImage = images[Math.floor(Math.random() * images.length)];
56+
setBgImage(randomImage);
57+
setBgImageName(parseWallpaperName(randomImage.split('/').pop()));
58+
59+
const fetchAuthorData = async () => {
60+
try {
61+
const response = await fetch(`${process.env.PUBLIC_URL}/stories/books.piml`);
62+
if (!response.ok) {
63+
throw new Error(`HTTP error! status: ${response.status}`);
64+
}
65+
const pimlText = await response.text();
66+
const data = piml.parse(pimlText);
67+
setAuthors(data.authors);
68+
setBooks(data.books);
69+
} catch (error) {
70+
console.error("Failed to fetch author data:", error);
71+
}
72+
};
73+
74+
fetchAuthorData();
75+
}, [setBreadcrumbs, setBgImageName]);
76+
77+
const getBooksByAuthor = (authorName, authorAlias) => {
78+
const authorBooks = [];
79+
books.forEach(book => {
80+
book.episodes.forEach(episode => {
81+
if ((episode.author === authorName || episode.author === authorAlias) && !authorBooks.some(b => b.bookTitle === book.bookTitle)) {
82+
authorBooks.push({
83+
bookId: book.bookId,
84+
bookTitle: book.bookTitle,
85+
});
86+
}
87+
});
88+
});
89+
return authorBooks;
90+
};
91+
3892
return (
3993
<motion.div
4094
initial="initial"
@@ -44,12 +98,21 @@ function DndAuthorsPage() {
4498
transition={pageTransition}
4599
className="dnd-page-container"
46100
>
47-
<div className="dnd-hero" style={{ backgroundImage: `url(${process.env.PUBLIC_URL}/images/stories/border-large.jpg)` }}>
101+
<div className="dnd-hero" style={{ backgroundImage: `url(${process.env.PUBLIC_URL}${bgImage})` }}>
48102
<h1 className="dnd-title-box">
49103
<span className="dnd-hero-title-white">Authors</span>
50104
</h1>
51-
<div className="dnd-content-box" style={{ zIndex: 1 }}>
52-
<p>This is the Authors page. Details about authors will be displayed here.</p>
105+
<div className="dnd-cards-container" style={{ zIndex: 1 }}>
106+
{authors.map((author, index) => (
107+
<DndAuthorCard
108+
key={index}
109+
authorName={author.name}
110+
authorWebsite={author.website}
111+
authorImage={author.image}
112+
authorAlias={author.alias} // Pass the alias
113+
booksWritten={getBooksByAuthor(author.name, author.alias)}
114+
/>
115+
))}
53116
</div>
54117
</div>
55118
</motion.div>

src/styles/dnd.css

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,107 @@
248248

249249
}
250250

251+
.dnd-author-card {
252+
background-color: rgba(50, 30, 30, 0.7); /* Similar to about card */
253+
padding: 1.5rem;
254+
width: 350px; /* Fixed width for consistency with dnd-card */
255+
border: 1px solid rgba(255, 255, 255, 0.1);
256+
border-radius: 8px;
257+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
258+
color: #E8E0B0;
259+
line-height: 1.6;
260+
position: relative;
261+
z-index: 1;
262+
text-align: center;
263+
display: flex;
264+
flex-direction: column;
265+
align-items: center;
266+
gap: 0.5rem;
267+
}
268+
269+
.dnd-author-image {
270+
width: 100px;
271+
height: 100px;
272+
border-radius: 50%;
273+
object-fit: cover;
274+
border: 2px solid #CD7F32; /* Bronze border */
275+
margin-bottom: 0.5rem;
276+
}
277+
278+
.dnd-author-name {
279+
font-family: 'Grenze Gotisch', cursive;
280+
font-size: 1.8rem;
281+
color: #ff9d7e;
282+
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
283+
-webkit-text-stroke: 1px #000;
284+
font-weight: 600;
285+
margin-bottom: 0.5rem;
286+
}
287+
288+
.dnd-author-alias {
289+
font-size: 1.1rem;
290+
color: #E8E0B0;
291+
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
292+
margin-bottom: 0.5rem;
293+
}
294+
295+
.dnd-author-website a {
296+
color: #FA8072; /* Salmon Red */
297+
text-decoration: none;
298+
font-size: 1.1rem;
299+
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
300+
}
301+
302+
.dnd-author-website a:hover {
303+
color: #ff8c00; /* DarkOrange */
304+
text-decoration: underline;
305+
}
306+
307+
.dnd-author-books {
308+
margin-top: 1rem;
309+
text-align: left;
310+
width: 100%;
311+
}
312+
313+
.dnd-author-books h4 {
314+
color: #FFFACD;
315+
font-size: 1.3rem;
316+
margin-bottom: 0.5rem;
317+
text-shadow: 1px 1px 3px rgba(0, 0, 0, 1);
318+
text-align: center;
319+
}
320+
321+
.dnd-author-books-separator {
322+
border: none;
323+
height: 2px;
324+
background-color: #CD7F32; /* Bronze color, similar to card border */
325+
margin: 0.5rem auto 1rem auto;
326+
width: 80%;
327+
}
328+
329+
.dnd-author-books ul {
330+
list-style: none;
331+
padding: 0;
332+
margin: 0 auto; /* Center the list */
333+
width: 80%; /* Match the width of the hr */
334+
}
335+
336+
.dnd-author-books li {
337+
font-size: 1rem;
338+
margin-bottom: 0.3rem;
339+
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
340+
}
341+
342+
.dnd-author-books li a {
343+
color: #FA8072; /* Salmon Red */
344+
text-decoration: none;
345+
}
346+
347+
.dnd-author-books li a:hover {
348+
color: #FFB03A;
349+
text-decoration: underline;
350+
}
351+
251352
.dnd-content-box h2 {
252353

253354
color: #FFFACD;

0 commit comments

Comments
 (0)