@fullstackdatasolutions/articles 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +243 -0
- package/README.md +226 -29
- package/dist/index.cjs +635 -274
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +165 -56
- package/dist/index.d.ts +165 -56
- package/dist/index.js +614 -250
- package/dist/index.js.map +1 -1
- package/dist/nextjs.cjs +40 -5
- package/dist/nextjs.cjs.map +1 -1
- package/dist/nextjs.d.cts +72 -0
- package/dist/nextjs.d.ts +72 -0
- package/dist/nextjs.js +40 -5
- package/dist/nextjs.js.map +1 -1
- package/dist/server.cjs +280 -16
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +92 -3
- package/dist/server.d.ts +92 -3
- package/dist/server.js +269 -16
- package/dist/server.js.map +1 -1
- package/package.json +8 -5
- package/src/ArticleDetailHero.tsx +27 -2
- package/src/ArticleSchemas.tsx +27 -27
- package/src/AuthorArticlesPage.tsx +60 -0
- package/src/AuthorCard.tsx +112 -0
- package/src/AuthorDetailHero.tsx +56 -0
- package/src/Breadcrumb.tsx +78 -0
- package/src/CategoryArticlesPage.tsx +62 -11
- package/src/__tests__/ArticleDetailHero.test.tsx +21 -1
- package/src/__tests__/ArticleSchemas.test.tsx +47 -2
- package/src/__tests__/AuthorArticlesPage.test.tsx +74 -0
- package/src/__tests__/AuthorCard.test.tsx +98 -0
- package/src/__tests__/AuthorDetailHero.test.tsx +51 -0
- package/src/__tests__/CategoryArticlesPage.test.tsx +31 -5
- package/src/__tests__/articlesConfig.test.ts +20 -1
- package/src/__tests__/authorUtils.test.ts +89 -0
- package/src/__tests__/renderMdx.test.tsx +113 -0
- package/src/__tests__/seoUtils-authors.test.ts +160 -0
- package/src/__tests__/seoUtils.test.ts +4 -0
- package/src/__tests__/server-articles.test.ts +159 -2
- package/src/articleTypes.ts +33 -0
- package/src/articlesConfig.ts +68 -0
- package/src/authorUtils.ts +95 -0
- package/src/index.ts +32 -9
- package/src/renderMdx.tsx +8 -2
- package/src/seoUtils.ts +226 -7
- package/src/server-articles.ts +98 -10
- package/src/server.ts +19 -1
package/dist/index.js
CHANGED
|
@@ -90,44 +90,177 @@ function ArticleCategoryGrid({ categories, pageSize = 8 }) {
|
|
|
90
90
|
] }) });
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
// src/
|
|
93
|
+
// src/authorUtils.ts
|
|
94
|
+
function getAuthorUrl(author) {
|
|
95
|
+
var _a;
|
|
96
|
+
return (_a = author.url) != null ? _a : `/articles/authors/${author.slug}`;
|
|
97
|
+
}
|
|
98
|
+
function getAuthorAvatar(author, config) {
|
|
99
|
+
if (!author.avatar) return void 0;
|
|
100
|
+
if (author.avatar.startsWith("http://") || author.avatar.startsWith("https://")) {
|
|
101
|
+
return author.avatar;
|
|
102
|
+
}
|
|
103
|
+
const path = `/articles/authors/${author.slug}/${author.avatar.replace(/^\/+/, "")}`;
|
|
104
|
+
if (!config) return path;
|
|
105
|
+
return `${config.siteUrl.replace(/\/$/, "")}${path}`;
|
|
106
|
+
}
|
|
107
|
+
function getAuthorSameAs(author) {
|
|
108
|
+
return getAuthorSocialLinks(author).map((link) => link.href);
|
|
109
|
+
}
|
|
110
|
+
function normalizeHandle(value) {
|
|
111
|
+
return value.replace(/^@/, "");
|
|
112
|
+
}
|
|
113
|
+
function normalizeUrl(value, baseUrl) {
|
|
114
|
+
if (value.startsWith("http://") || value.startsWith("https://")) return value;
|
|
115
|
+
if (!baseUrl) return value;
|
|
116
|
+
return `${baseUrl}${normalizeHandle(value)}`;
|
|
117
|
+
}
|
|
118
|
+
function getConfiguredSocialLinks(social) {
|
|
119
|
+
var _a, _b;
|
|
120
|
+
return [
|
|
121
|
+
{ label: "Website", href: (_a = social.website) != null ? _a : "" },
|
|
122
|
+
{
|
|
123
|
+
label: "Facebook",
|
|
124
|
+
href: social.facebook ? normalizeUrl(social.facebook, "https://www.facebook.com/") : ""
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
label: "Twitter",
|
|
128
|
+
href: social.twitter ? normalizeUrl(social.twitter, "https://twitter.com/") : ""
|
|
129
|
+
},
|
|
130
|
+
{ label: "X", href: social.x ? normalizeUrl(social.x, "https://x.com/") : "" },
|
|
131
|
+
{
|
|
132
|
+
label: "LinkedIn",
|
|
133
|
+
href: social.linkedin ? normalizeUrl(social.linkedin, "https://www.linkedin.com/in/") : ""
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
label: "Instagram",
|
|
137
|
+
href: social.instagram ? normalizeUrl(social.instagram, "https://www.instagram.com/") : ""
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
label: "YouTube",
|
|
141
|
+
href: social.youtube ? normalizeUrl(social.youtube, "https://www.youtube.com/") : ""
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
label: "TikTok",
|
|
145
|
+
href: social.tiktok ? normalizeUrl(social.tiktok, "https://www.tiktok.com/@") : ""
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
label: "GitHub",
|
|
149
|
+
href: social.github ? normalizeUrl(social.github, "https://github.com/") : ""
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
label: "Bluesky",
|
|
153
|
+
href: social.bluesky ? normalizeUrl(social.bluesky, "https://bsky.app/profile/") : ""
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
label: "Threads",
|
|
157
|
+
href: social.threads ? normalizeUrl(social.threads, "https://www.threads.net/@") : ""
|
|
158
|
+
},
|
|
159
|
+
{ label: "Mastodon", href: social.mastodon ? normalizeUrl(social.mastodon) : "" },
|
|
160
|
+
{
|
|
161
|
+
label: "Medium",
|
|
162
|
+
href: social.medium ? normalizeUrl(social.medium, "https://medium.com/@") : ""
|
|
163
|
+
},
|
|
164
|
+
{ label: "Newsletter", href: (_b = social.newsletter) != null ? _b : "" }
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
function getAuthorSocialLinks(author) {
|
|
168
|
+
var _a;
|
|
169
|
+
const social = author.social;
|
|
170
|
+
if (!social) return [];
|
|
171
|
+
const configuredLinks = getConfiguredSocialLinks(social);
|
|
172
|
+
const otherLinks = Object.entries((_a = social.other) != null ? _a : {}).map(([label, href]) => ({ label, href }));
|
|
173
|
+
return [...configuredLinks, ...otherLinks].filter((link) => link.href.trim().length > 0);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/Breadcrumb.tsx
|
|
177
|
+
import Link2 from "next/link";
|
|
94
178
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
179
|
+
function buildBreadcrumbSchema(items) {
|
|
180
|
+
return {
|
|
181
|
+
"@context": "https://schema.org",
|
|
182
|
+
"@type": "BreadcrumbList",
|
|
183
|
+
itemListElement: items.map((item, index) => __spreadValues({
|
|
184
|
+
"@type": "ListItem",
|
|
185
|
+
position: index + 1,
|
|
186
|
+
name: item.name
|
|
187
|
+
}, item.url && { item: item.url }))
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function getDisplayItems(items) {
|
|
191
|
+
if (items.length <= 4) return [...items];
|
|
192
|
+
return [items[0], { name: "..." }, ...items.slice(-2)];
|
|
193
|
+
}
|
|
194
|
+
function Breadcrumb({
|
|
195
|
+
items,
|
|
196
|
+
className = "",
|
|
197
|
+
showSchema = true,
|
|
198
|
+
separator = ">"
|
|
199
|
+
}) {
|
|
200
|
+
if (items.length === 0) return null;
|
|
201
|
+
const displayItems = getDisplayItems(items);
|
|
202
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
203
|
+
/* @__PURE__ */ jsx2(
|
|
204
|
+
"nav",
|
|
205
|
+
{
|
|
206
|
+
"aria-label": "Breadcrumb",
|
|
207
|
+
className: `border-b border-border bg-background/80 px-4 py-3 text-sm text-muted-foreground ${className}`,
|
|
208
|
+
children: /* @__PURE__ */ jsx2("ol", { className: "mx-auto flex max-w-7xl items-center gap-2 overflow-hidden", children: displayItems.map((item, index) => {
|
|
209
|
+
const isLast = index === displayItems.length - 1;
|
|
210
|
+
const key = `${item.name}-${index}`;
|
|
211
|
+
return /* @__PURE__ */ jsxs2("li", { className: "flex min-w-0 items-center gap-2", children: [
|
|
212
|
+
index > 0 && /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", children: separator }),
|
|
213
|
+
item.url && !isLast ? /* @__PURE__ */ jsx2(Link2, { href: item.url, className: "truncate hover:text-foreground", children: item.name }) : /* @__PURE__ */ jsx2("span", { className: "truncate", "aria-current": isLast ? "page" : void 0, children: item.name })
|
|
214
|
+
] }, key);
|
|
215
|
+
}) })
|
|
216
|
+
}
|
|
217
|
+
),
|
|
218
|
+
showSchema && /* @__PURE__ */ jsx2(
|
|
219
|
+
"script",
|
|
220
|
+
{
|
|
221
|
+
type: "application/ld+json",
|
|
222
|
+
dangerouslySetInnerHTML: { __html: JSON.stringify(buildBreadcrumbSchema(items)) }
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
] });
|
|
226
|
+
}
|
|
227
|
+
function BreadcrumbSchema({ items }) {
|
|
228
|
+
return /* @__PURE__ */ jsx2(Breadcrumb, { items, showSchema: true, className: "sr-only" });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/ArticleSchemas.tsx
|
|
232
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
233
|
+
function getPersonSchemas(article, authors) {
|
|
234
|
+
let resolvedAuthors = [];
|
|
235
|
+
if (authors == null ? void 0 : authors.length) {
|
|
236
|
+
resolvedAuthors = [...authors];
|
|
237
|
+
} else if (article.author) {
|
|
238
|
+
resolvedAuthors = [{ name: article.author, slug: "", bio: "" }];
|
|
239
|
+
}
|
|
240
|
+
return resolvedAuthors.map((author) => __spreadValues(__spreadValues({
|
|
241
|
+
"@type": "Person",
|
|
242
|
+
name: author.name
|
|
243
|
+
}, author.url && { url: author.url }), getAuthorSameAs(author).length > 0 && { sameAs: getAuthorSameAs(author) }));
|
|
244
|
+
}
|
|
95
245
|
function ArticleSchema({
|
|
96
246
|
article,
|
|
97
247
|
articleUrl,
|
|
98
248
|
siteName,
|
|
99
|
-
showAuthor = true
|
|
249
|
+
showAuthor = true,
|
|
250
|
+
authors
|
|
100
251
|
}) {
|
|
252
|
+
const personSchemas = getPersonSchemas(article, authors);
|
|
101
253
|
const schema = __spreadProps(__spreadValues(__spreadValues({
|
|
102
254
|
"@context": "https://schema.org",
|
|
103
255
|
"@type": "Article",
|
|
104
256
|
headline: article.title,
|
|
105
257
|
description: article.excerpt,
|
|
106
258
|
image: article.featuredImage
|
|
107
|
-
}, article.date && { datePublished: new Date(article.date).toISOString() }), showAuthor &&
|
|
259
|
+
}, article.date && { datePublished: new Date(article.date).toISOString() }), showAuthor && personSchemas.length > 0 && { author: personSchemas }), {
|
|
108
260
|
publisher: { "@type": "Organization", name: siteName },
|
|
109
261
|
mainEntityOfPage: { "@type": "WebPage", "@id": articleUrl }
|
|
110
262
|
});
|
|
111
|
-
return /* @__PURE__ */
|
|
112
|
-
"script",
|
|
113
|
-
{
|
|
114
|
-
type: "application/ld+json",
|
|
115
|
-
dangerouslySetInnerHTML: { __html: JSON.stringify(schema) }
|
|
116
|
-
}
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
function BreadcrumbSchema({ items }) {
|
|
120
|
-
const schema = {
|
|
121
|
-
"@context": "https://schema.org",
|
|
122
|
-
"@type": "BreadcrumbList",
|
|
123
|
-
itemListElement: items.map((item, index) => ({
|
|
124
|
-
"@type": "ListItem",
|
|
125
|
-
position: index + 1,
|
|
126
|
-
name: item.name,
|
|
127
|
-
item: item.url
|
|
128
|
-
}))
|
|
129
|
-
};
|
|
130
|
-
return /* @__PURE__ */ jsx2(
|
|
263
|
+
return /* @__PURE__ */ jsx3(
|
|
131
264
|
"script",
|
|
132
265
|
{
|
|
133
266
|
type: "application/ld+json",
|
|
@@ -140,32 +273,34 @@ function ArticleSEO({
|
|
|
140
273
|
articleUrl,
|
|
141
274
|
siteName,
|
|
142
275
|
siteLogo,
|
|
143
|
-
showAuthor = true
|
|
276
|
+
showAuthor = true,
|
|
277
|
+
authors
|
|
144
278
|
}) {
|
|
145
279
|
const publishedAt = article.date ? new Date(article.date).toISOString() : void 0;
|
|
146
280
|
const modifiedAt = article.lastmod ? new Date(article.lastmod).toISOString() : publishedAt;
|
|
281
|
+
const personSchemas = getPersonSchemas(article, authors);
|
|
147
282
|
const structuredData = __spreadValues(__spreadProps(__spreadValues(__spreadValues(__spreadValues({
|
|
148
283
|
"@context": "https://schema.org",
|
|
149
284
|
"@type": article.articleType || "Article",
|
|
150
285
|
mainEntityOfPage: { "@type": "WebPage", "@id": articleUrl },
|
|
151
286
|
headline: article.title,
|
|
152
287
|
image: article.featuredImage ? { "@type": "ImageObject", url: article.featuredImage } : void 0
|
|
153
|
-
}, publishedAt && { datePublished: publishedAt }), modifiedAt && { dateModified: modifiedAt }), showAuthor &&
|
|
288
|
+
}, publishedAt && { datePublished: publishedAt }), modifiedAt && { dateModified: modifiedAt }), showAuthor && personSchemas.length > 0 && { author: personSchemas }), {
|
|
154
289
|
publisher: __spreadValues({
|
|
155
290
|
"@type": "Organization",
|
|
156
291
|
name: siteName
|
|
157
292
|
}, siteLogo && { logo: { "@type": "ImageObject", url: siteLogo } }),
|
|
158
293
|
description: article.excerpt
|
|
159
294
|
}), article.series && { isPartOf: { "@type": "Blog", name: article.series } });
|
|
160
|
-
return /* @__PURE__ */
|
|
161
|
-
/* @__PURE__ */
|
|
295
|
+
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
296
|
+
/* @__PURE__ */ jsx3(
|
|
162
297
|
"script",
|
|
163
298
|
{
|
|
164
299
|
type: "application/ld+json",
|
|
165
300
|
dangerouslySetInnerHTML: { __html: JSON.stringify(structuredData) }
|
|
166
301
|
}
|
|
167
302
|
),
|
|
168
|
-
article.faq && article.faq.length > 0 && /* @__PURE__ */
|
|
303
|
+
article.faq && article.faq.length > 0 && /* @__PURE__ */ jsx3(
|
|
169
304
|
"script",
|
|
170
305
|
{
|
|
171
306
|
type: "application/ld+json",
|
|
@@ -182,7 +317,7 @@ function ArticleSEO({
|
|
|
182
317
|
}
|
|
183
318
|
}
|
|
184
319
|
),
|
|
185
|
-
article.howTo && article.howTo.length > 0 && /* @__PURE__ */
|
|
320
|
+
article.howTo && article.howTo.length > 0 && /* @__PURE__ */ jsx3(
|
|
186
321
|
"script",
|
|
187
322
|
{
|
|
188
323
|
type: "application/ld+json",
|
|
@@ -212,7 +347,7 @@ function FAQPageSchema({ items }) {
|
|
|
212
347
|
acceptedAnswer: { "@type": "Answer", text: answer }
|
|
213
348
|
}))
|
|
214
349
|
};
|
|
215
|
-
return /* @__PURE__ */
|
|
350
|
+
return /* @__PURE__ */ jsx3(
|
|
216
351
|
"script",
|
|
217
352
|
{
|
|
218
353
|
type: "application/ld+json",
|
|
@@ -234,7 +369,7 @@ function CollectionPageSchema({
|
|
|
234
369
|
url,
|
|
235
370
|
numberOfItems: articleCount
|
|
236
371
|
};
|
|
237
|
-
return /* @__PURE__ */
|
|
372
|
+
return /* @__PURE__ */ jsx3(
|
|
238
373
|
"script",
|
|
239
374
|
{
|
|
240
375
|
type: "application/ld+json",
|
|
@@ -245,17 +380,17 @@ function CollectionPageSchema({
|
|
|
245
380
|
|
|
246
381
|
// src/ArticleSearchBar.tsx
|
|
247
382
|
import { Search, X } from "lucide-react";
|
|
248
|
-
import { jsx as
|
|
383
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
249
384
|
function ArticleSearchBar({
|
|
250
385
|
value,
|
|
251
386
|
onChange,
|
|
252
387
|
disabled,
|
|
253
388
|
resultCount
|
|
254
389
|
}) {
|
|
255
|
-
return /* @__PURE__ */
|
|
256
|
-
/* @__PURE__ */
|
|
257
|
-
/* @__PURE__ */
|
|
258
|
-
/* @__PURE__ */
|
|
390
|
+
return /* @__PURE__ */ jsx4("section", { className: "py-8 bg-background border-b border-border", children: /* @__PURE__ */ jsxs4("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8", children: [
|
|
391
|
+
/* @__PURE__ */ jsxs4("div", { className: "relative", children: [
|
|
392
|
+
/* @__PURE__ */ jsx4(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5" }),
|
|
393
|
+
/* @__PURE__ */ jsx4(
|
|
259
394
|
"input",
|
|
260
395
|
{
|
|
261
396
|
type: "text",
|
|
@@ -266,44 +401,44 @@ function ArticleSearchBar({
|
|
|
266
401
|
className: "flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 pl-10 pr-10 py-3 text-lg"
|
|
267
402
|
}
|
|
268
403
|
),
|
|
269
|
-
value && /* @__PURE__ */
|
|
404
|
+
value && /* @__PURE__ */ jsx4(
|
|
270
405
|
"button",
|
|
271
406
|
{
|
|
272
407
|
type: "button",
|
|
273
408
|
onClick: () => onChange(""),
|
|
274
409
|
"aria-label": "Clear search",
|
|
275
410
|
className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
276
|
-
children: /* @__PURE__ */
|
|
411
|
+
children: /* @__PURE__ */ jsx4(X, { className: "h-5 w-5" })
|
|
277
412
|
}
|
|
278
413
|
)
|
|
279
414
|
] }),
|
|
280
|
-
value && /* @__PURE__ */
|
|
415
|
+
value && /* @__PURE__ */ jsx4("div", { className: "mt-2 text-sm text-muted-foreground", children: resultCount === 0 ? "No articles found matching your search." : `Found ${resultCount} article${resultCount === 1 ? "" : "s"} matching "${value}"` })
|
|
281
416
|
] }) });
|
|
282
417
|
}
|
|
283
418
|
|
|
284
419
|
// src/ArticlesHero.tsx
|
|
285
|
-
import
|
|
286
|
-
import { jsx as
|
|
420
|
+
import Link3 from "next/link";
|
|
421
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
287
422
|
var DEFAULT_TITLE = "Vox Populus Insights";
|
|
288
423
|
var DEFAULT_DESCRIPTION = "Expert analysis, campaign strategies, and voter engagement insights from the frontlines of democracy.";
|
|
289
424
|
function ArticlesHero({
|
|
290
425
|
title = DEFAULT_TITLE,
|
|
291
426
|
description = DEFAULT_DESCRIPTION
|
|
292
427
|
}) {
|
|
293
|
-
return /* @__PURE__ */
|
|
294
|
-
/* @__PURE__ */
|
|
295
|
-
/* @__PURE__ */
|
|
296
|
-
/* @__PURE__ */
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
|
|
428
|
+
return /* @__PURE__ */ jsx5("section", { className: "bg-linear-to-r from-gray-50 to-gray-100 py-16 md:py-24", children: /* @__PURE__ */ jsx5("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs5("div", { className: "max-w-3xl mx-auto text-center", children: [
|
|
429
|
+
/* @__PURE__ */ jsx5("h1", { className: "text-4xl md:text-5xl font-bold text-foreground mb-6", children: title }),
|
|
430
|
+
/* @__PURE__ */ jsx5("p", { className: "text-xl text-muted-foreground mb-8", children: description }),
|
|
431
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col sm:flex-row gap-4 justify-center", children: [
|
|
432
|
+
/* @__PURE__ */ jsx5(
|
|
433
|
+
Link3,
|
|
299
434
|
{
|
|
300
435
|
href: "#latest",
|
|
301
436
|
className: "inline-flex items-center justify-center px-4 py-2 bg-primary hover:bg-primary/90 text-primary-foreground rounded-md font-medium text-sm transition-colors",
|
|
302
437
|
children: "Browse Latest Articles"
|
|
303
438
|
}
|
|
304
439
|
),
|
|
305
|
-
/* @__PURE__ */
|
|
306
|
-
|
|
440
|
+
/* @__PURE__ */ jsx5(
|
|
441
|
+
Link3,
|
|
307
442
|
{
|
|
308
443
|
href: "/contact",
|
|
309
444
|
className: "inline-flex items-center justify-center px-4 py-2 border border-primary text-primary hover:bg-primary/10 rounded-md font-medium text-sm transition-colors",
|
|
@@ -315,44 +450,44 @@ function ArticlesHero({
|
|
|
315
450
|
}
|
|
316
451
|
|
|
317
452
|
// src/FeaturedArticle.tsx
|
|
318
|
-
import
|
|
453
|
+
import Link4 from "next/link";
|
|
319
454
|
import Image2 from "next/image";
|
|
320
455
|
import { ArrowRight, Calendar, Clock, User } from "lucide-react";
|
|
321
|
-
import { jsx as
|
|
456
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
322
457
|
function FeaturedArticle({ article, showAuthor = true }) {
|
|
323
|
-
return /* @__PURE__ */
|
|
324
|
-
/* @__PURE__ */
|
|
325
|
-
/* @__PURE__ */
|
|
326
|
-
/* @__PURE__ */
|
|
327
|
-
/* @__PURE__ */
|
|
328
|
-
/* @__PURE__ */
|
|
329
|
-
article.date && /* @__PURE__ */
|
|
330
|
-
/* @__PURE__ */
|
|
331
|
-
/* @__PURE__ */
|
|
458
|
+
return /* @__PURE__ */ jsx6("section", { className: "py-16 bg-background", children: /* @__PURE__ */ jsx6("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs6("div", { className: "grid lg:grid-cols-2 gap-12 items-center", children: [
|
|
459
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
460
|
+
/* @__PURE__ */ jsx6("span", { className: "inline-block bg-primary/10 text-primary text-sm font-medium px-3 py-1 rounded-full mb-4", children: "FEATURED ARTICLE" }),
|
|
461
|
+
/* @__PURE__ */ jsx6("h2", { className: "text-3xl font-bold text-foreground mb-4", children: article.title }),
|
|
462
|
+
/* @__PURE__ */ jsx6("p", { className: "text-lg text-muted-foreground mb-6", children: article.excerpt }),
|
|
463
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-6 text-sm text-muted-foreground mb-6", children: [
|
|
464
|
+
article.date && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
465
|
+
/* @__PURE__ */ jsx6(Calendar, { className: "h-4 w-4" }),
|
|
466
|
+
/* @__PURE__ */ jsx6("span", { children: article.date })
|
|
332
467
|
] }),
|
|
333
|
-
/* @__PURE__ */
|
|
334
|
-
/* @__PURE__ */
|
|
335
|
-
/* @__PURE__ */
|
|
468
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
469
|
+
/* @__PURE__ */ jsx6(Clock, { className: "h-4 w-4" }),
|
|
470
|
+
/* @__PURE__ */ jsx6("span", { children: article.readTime })
|
|
336
471
|
] }),
|
|
337
|
-
showAuthor && /* @__PURE__ */
|
|
338
|
-
/* @__PURE__ */
|
|
339
|
-
/* @__PURE__ */
|
|
472
|
+
showAuthor && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
473
|
+
/* @__PURE__ */ jsx6(User, { className: "h-4 w-4" }),
|
|
474
|
+
/* @__PURE__ */ jsx6("span", { children: article.author })
|
|
340
475
|
] })
|
|
341
476
|
] }),
|
|
342
|
-
/* @__PURE__ */
|
|
343
|
-
|
|
477
|
+
/* @__PURE__ */ jsxs6(
|
|
478
|
+
Link4,
|
|
344
479
|
{
|
|
345
480
|
href: `/articles/${article.slug}`,
|
|
346
481
|
className: "inline-flex items-center justify-center px-4 py-2 bg-primary hover:bg-primary/90 text-primary-foreground rounded-md font-medium text-sm transition-colors",
|
|
347
482
|
children: [
|
|
348
483
|
"Read Full Article",
|
|
349
|
-
/* @__PURE__ */
|
|
484
|
+
/* @__PURE__ */ jsx6(ArrowRight, { className: "ml-2 h-4 w-4" })
|
|
350
485
|
]
|
|
351
486
|
}
|
|
352
487
|
)
|
|
353
488
|
] }),
|
|
354
|
-
/* @__PURE__ */
|
|
355
|
-
/* @__PURE__ */
|
|
489
|
+
/* @__PURE__ */ jsxs6("div", { className: "bg-card rounded-lg p-8", children: [
|
|
490
|
+
/* @__PURE__ */ jsx6(
|
|
356
491
|
Image2,
|
|
357
492
|
{
|
|
358
493
|
src: article.featuredImage,
|
|
@@ -362,7 +497,7 @@ function FeaturedArticle({ article, showAuthor = true }) {
|
|
|
362
497
|
className: "w-full h-64 object-cover rounded-lg mb-4"
|
|
363
498
|
}
|
|
364
499
|
),
|
|
365
|
-
/* @__PURE__ */
|
|
500
|
+
/* @__PURE__ */ jsx6("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx6("span", { className: "bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded", children: article.category }) })
|
|
366
501
|
] })
|
|
367
502
|
] }) }) });
|
|
368
503
|
}
|
|
@@ -375,12 +510,12 @@ import { useState as useState2, useEffect as useEffect2 } from "react";
|
|
|
375
510
|
|
|
376
511
|
// src/ArticleCard.tsx
|
|
377
512
|
import Image3 from "next/image";
|
|
378
|
-
import
|
|
513
|
+
import Link5 from "next/link";
|
|
379
514
|
import { ArrowRight as ArrowRight2, Calendar as Calendar2, Clock as Clock2 } from "lucide-react";
|
|
380
|
-
import { jsx as
|
|
515
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
381
516
|
function ArticleCard({ article }) {
|
|
382
|
-
return /* @__PURE__ */
|
|
383
|
-
/* @__PURE__ */
|
|
517
|
+
return /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border bg-card text-card-foreground shadow-sm hover:shadow-lg transition-shadow duration-300", children: [
|
|
518
|
+
/* @__PURE__ */ jsx7("div", { className: "p-0", children: /* @__PURE__ */ jsx7(
|
|
384
519
|
Image3,
|
|
385
520
|
{
|
|
386
521
|
src: article.featuredImage,
|
|
@@ -390,35 +525,35 @@ function ArticleCard({ article }) {
|
|
|
390
525
|
height: 200
|
|
391
526
|
}
|
|
392
527
|
) }),
|
|
393
|
-
/* @__PURE__ */
|
|
394
|
-
/* @__PURE__ */
|
|
395
|
-
/* @__PURE__ */
|
|
396
|
-
|
|
528
|
+
/* @__PURE__ */ jsxs7("div", { className: "p-6", children: [
|
|
529
|
+
/* @__PURE__ */ jsx7("div", { className: "flex gap-2 mb-3", children: /* @__PURE__ */ jsx7("span", { className: "bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded", children: article.category }) }),
|
|
530
|
+
/* @__PURE__ */ jsx7("h3", { className: "text-lg font-semibold leading-none tracking-tight mb-2", children: /* @__PURE__ */ jsx7(
|
|
531
|
+
Link5,
|
|
397
532
|
{
|
|
398
533
|
href: `/articles/${article.slug}`,
|
|
399
534
|
className: "hover:text-indigo-600 transition-colors",
|
|
400
535
|
children: article.title
|
|
401
536
|
}
|
|
402
537
|
) }),
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
/* @__PURE__ */
|
|
405
|
-
/* @__PURE__ */
|
|
406
|
-
article.date && /* @__PURE__ */
|
|
407
|
-
/* @__PURE__ */
|
|
408
|
-
/* @__PURE__ */
|
|
538
|
+
/* @__PURE__ */ jsx7("p", { className: "text-muted-foreground mb-4 line-clamp-3", children: article.excerpt }),
|
|
539
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between text-sm text-muted-foreground border-t pt-4", children: [
|
|
540
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
|
|
541
|
+
article.date && /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
542
|
+
/* @__PURE__ */ jsx7(Calendar2, { className: "h-3 w-3" }),
|
|
543
|
+
/* @__PURE__ */ jsx7("span", { children: article.date })
|
|
409
544
|
] }),
|
|
410
|
-
/* @__PURE__ */
|
|
411
|
-
/* @__PURE__ */
|
|
412
|
-
/* @__PURE__ */
|
|
545
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
546
|
+
/* @__PURE__ */ jsx7(Clock2, { className: "h-3 w-3" }),
|
|
547
|
+
/* @__PURE__ */ jsx7("span", { children: article.readTime })
|
|
413
548
|
] })
|
|
414
549
|
] }),
|
|
415
|
-
/* @__PURE__ */
|
|
416
|
-
|
|
550
|
+
/* @__PURE__ */ jsx7(
|
|
551
|
+
Link5,
|
|
417
552
|
{
|
|
418
553
|
href: `/articles/${article.slug}`,
|
|
419
554
|
className: "inline-flex items-center justify-center h-8 w-8 p-0 rounded-md hover:bg-accent transition-colors",
|
|
420
555
|
"aria-label": `Read ${article.title}`,
|
|
421
|
-
children: /* @__PURE__ */
|
|
556
|
+
children: /* @__PURE__ */ jsx7(ArrowRight2, { className: "h-4 w-4" })
|
|
422
557
|
}
|
|
423
558
|
)
|
|
424
559
|
] })
|
|
@@ -427,7 +562,7 @@ function ArticleCard({ article }) {
|
|
|
427
562
|
}
|
|
428
563
|
|
|
429
564
|
// src/LatestArticles.tsx
|
|
430
|
-
import { jsx as
|
|
565
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
431
566
|
function LatestArticles({ articles, pageSize }) {
|
|
432
567
|
const [visibleCount, setVisibleCount] = useState2(pageSize);
|
|
433
568
|
useEffect2(() => {
|
|
@@ -435,9 +570,9 @@ function LatestArticles({ articles, pageSize }) {
|
|
|
435
570
|
}, [articles, pageSize]);
|
|
436
571
|
const visible = articles.slice(0, visibleCount);
|
|
437
572
|
const hasMore = visibleCount < articles.length;
|
|
438
|
-
return /* @__PURE__ */
|
|
439
|
-
/* @__PURE__ */
|
|
440
|
-
hasMore && /* @__PURE__ */
|
|
573
|
+
return /* @__PURE__ */ jsxs8("div", { children: [
|
|
574
|
+
/* @__PURE__ */ jsx8("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-8", children: visible.map((article) => /* @__PURE__ */ jsx8(ArticleCard, { article }, article.slug)) }),
|
|
575
|
+
hasMore && /* @__PURE__ */ jsx8("div", { className: "mt-10 text-center", children: /* @__PURE__ */ jsx8(
|
|
441
576
|
"button",
|
|
442
577
|
{
|
|
443
578
|
type: "button",
|
|
@@ -450,14 +585,14 @@ function LatestArticles({ articles, pageSize }) {
|
|
|
450
585
|
}
|
|
451
586
|
|
|
452
587
|
// src/LatestArticlesSection.tsx
|
|
453
|
-
import { jsx as
|
|
588
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
454
589
|
function DescriptionText({
|
|
455
590
|
searchQuery,
|
|
456
591
|
count
|
|
457
592
|
}) {
|
|
458
593
|
const pluralSuffix = count === 1 ? "" : "s";
|
|
459
594
|
const text = searchQuery ? `Found ${count} article${pluralSuffix} matching your search.` : "Stay informed with our latest insights on voter engagement, campaign strategies, and civic technology.";
|
|
460
|
-
return /* @__PURE__ */
|
|
595
|
+
return /* @__PURE__ */ jsx9("p", { className: "text-lg text-muted-foreground", children: text });
|
|
461
596
|
}
|
|
462
597
|
function LatestArticlesSection({
|
|
463
598
|
articles,
|
|
@@ -465,20 +600,20 @@ function LatestArticlesSection({
|
|
|
465
600
|
onClearSearch,
|
|
466
601
|
pageSize = 6
|
|
467
602
|
}) {
|
|
468
|
-
return /* @__PURE__ */
|
|
469
|
-
/* @__PURE__ */
|
|
470
|
-
/* @__PURE__ */
|
|
471
|
-
/* @__PURE__ */
|
|
603
|
+
return /* @__PURE__ */ jsx9("section", { id: "latest", className: "py-16 bg-muted/50", children: /* @__PURE__ */ jsxs9("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
|
|
604
|
+
/* @__PURE__ */ jsxs9("div", { className: "text-center mb-12", children: [
|
|
605
|
+
/* @__PURE__ */ jsx9("h2", { className: "text-3xl font-bold text-foreground mb-4", children: searchQuery ? "Search Results" : "Latest Articles" }),
|
|
606
|
+
/* @__PURE__ */ jsx9(DescriptionText, { searchQuery, count: articles.length })
|
|
472
607
|
] }),
|
|
473
|
-
articles.length === 0 && searchQuery ? /* @__PURE__ */
|
|
474
|
-
/* @__PURE__ */
|
|
475
|
-
/* @__PURE__ */
|
|
476
|
-
/* @__PURE__ */
|
|
608
|
+
articles.length === 0 && searchQuery ? /* @__PURE__ */ jsx9("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxs9("div", { className: "max-w-md mx-auto", children: [
|
|
609
|
+
/* @__PURE__ */ jsx9(Search2, { className: "h-12 w-12 text-muted-foreground mx-auto mb-4" }),
|
|
610
|
+
/* @__PURE__ */ jsx9("h3", { className: "text-lg font-semibold text-foreground mb-2", children: "No articles found" }),
|
|
611
|
+
/* @__PURE__ */ jsxs9("p", { className: "text-muted-foreground mb-4", children: [
|
|
477
612
|
`We couldn't find any articles matching "`,
|
|
478
613
|
searchQuery,
|
|
479
614
|
'". Try adjusting your search terms.'
|
|
480
615
|
] }),
|
|
481
|
-
/* @__PURE__ */
|
|
616
|
+
/* @__PURE__ */ jsx9(
|
|
482
617
|
"button",
|
|
483
618
|
{
|
|
484
619
|
type: "button",
|
|
@@ -487,7 +622,7 @@ function LatestArticlesSection({
|
|
|
487
622
|
children: "Clear search"
|
|
488
623
|
}
|
|
489
624
|
)
|
|
490
|
-
] }) }) : /* @__PURE__ */
|
|
625
|
+
] }) }) : /* @__PURE__ */ jsx9(LatestArticles, { articles, pageSize }, searchQuery)
|
|
491
626
|
] }) });
|
|
492
627
|
}
|
|
493
628
|
|
|
@@ -501,6 +636,15 @@ var DEFAULT_LAYOUT = [
|
|
|
501
636
|
"latest",
|
|
502
637
|
"categories"
|
|
503
638
|
];
|
|
639
|
+
function breadcrumbsAreEnabled(config) {
|
|
640
|
+
var _a;
|
|
641
|
+
return config.breadcrumbs !== false && ((_a = config.breadcrumbs) == null ? void 0 : _a.show) !== false;
|
|
642
|
+
}
|
|
643
|
+
function getBreadcrumbsConfig(config) {
|
|
644
|
+
var _a;
|
|
645
|
+
if (config.breadcrumbs === false) return {};
|
|
646
|
+
return (_a = config.breadcrumbs) != null ? _a : {};
|
|
647
|
+
}
|
|
504
648
|
|
|
505
649
|
// src/useArticles.ts
|
|
506
650
|
import { useState as useState3, useCallback, useEffect as useEffect3, useRef } from "react";
|
|
@@ -571,7 +715,7 @@ function useArticles() {
|
|
|
571
715
|
}
|
|
572
716
|
|
|
573
717
|
// src/ArticlesPage.tsx
|
|
574
|
-
import { jsx as
|
|
718
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
575
719
|
function buildThemeVars(theme) {
|
|
576
720
|
if (!theme) return {};
|
|
577
721
|
const vars = {};
|
|
@@ -604,7 +748,7 @@ function renderSection(section, ctx, config) {
|
|
|
604
748
|
} = ctx;
|
|
605
749
|
switch (section) {
|
|
606
750
|
case "hero":
|
|
607
|
-
return /* @__PURE__ */
|
|
751
|
+
return /* @__PURE__ */ jsx10(
|
|
608
752
|
ArticlesHero,
|
|
609
753
|
{
|
|
610
754
|
title: (_a = config.hero) == null ? void 0 : _a.title,
|
|
@@ -613,7 +757,7 @@ function renderSection(section, ctx, config) {
|
|
|
613
757
|
"hero"
|
|
614
758
|
);
|
|
615
759
|
case "search":
|
|
616
|
-
return /* @__PURE__ */
|
|
760
|
+
return /* @__PURE__ */ jsx10(
|
|
617
761
|
ArticleSearchBar,
|
|
618
762
|
{
|
|
619
763
|
value: searchQuery,
|
|
@@ -624,7 +768,7 @@ function renderSection(section, ctx, config) {
|
|
|
624
768
|
"search"
|
|
625
769
|
);
|
|
626
770
|
case "featured":
|
|
627
|
-
return articles.length > 0 && !searchQuery ? /* @__PURE__ */
|
|
771
|
+
return articles.length > 0 && !searchQuery ? /* @__PURE__ */ jsx10(
|
|
628
772
|
FeaturedArticle,
|
|
629
773
|
{
|
|
630
774
|
article: articles[0],
|
|
@@ -634,16 +778,16 @@ function renderSection(section, ctx, config) {
|
|
|
634
778
|
) : null;
|
|
635
779
|
case "latest":
|
|
636
780
|
if (loading && articles.length === 0) {
|
|
637
|
-
return /* @__PURE__ */
|
|
638
|
-
/* @__PURE__ */
|
|
639
|
-
/* @__PURE__ */
|
|
781
|
+
return /* @__PURE__ */ jsx10("section", { id: "latest", className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsx10("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center py-24", children: /* @__PURE__ */ jsxs10("div", { className: "text-center", children: [
|
|
782
|
+
/* @__PURE__ */ jsx10("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4" }),
|
|
783
|
+
/* @__PURE__ */ jsx10("p", { className: "text-muted-foreground", children: "Loading articles..." })
|
|
640
784
|
] }) }) }, "latest");
|
|
641
785
|
}
|
|
642
786
|
if (error) {
|
|
643
|
-
return /* @__PURE__ */
|
|
644
|
-
/* @__PURE__ */
|
|
645
|
-
/* @__PURE__ */
|
|
646
|
-
/* @__PURE__ */
|
|
787
|
+
return /* @__PURE__ */ jsx10("section", { id: "latest", className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsx10("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center", children: /* @__PURE__ */ jsxs10("div", { className: "bg-red-50 border border-red-200 rounded-lg p-6 max-w-md text-center", children: [
|
|
788
|
+
/* @__PURE__ */ jsx10("h3", { className: "text-lg font-semibold text-red-800 mb-2", children: "Error Loading Articles" }),
|
|
789
|
+
/* @__PURE__ */ jsx10("p", { className: "text-red-600 mb-4", children: error }),
|
|
790
|
+
/* @__PURE__ */ jsx10(
|
|
647
791
|
"button",
|
|
648
792
|
{
|
|
649
793
|
type: "button",
|
|
@@ -654,7 +798,7 @@ function renderSection(section, ctx, config) {
|
|
|
654
798
|
)
|
|
655
799
|
] }) }) }, "latest");
|
|
656
800
|
}
|
|
657
|
-
return /* @__PURE__ */
|
|
801
|
+
return /* @__PURE__ */ jsx10(
|
|
658
802
|
LatestArticlesSection,
|
|
659
803
|
{
|
|
660
804
|
articles: displayedArticles,
|
|
@@ -665,7 +809,7 @@ function renderSection(section, ctx, config) {
|
|
|
665
809
|
"latest"
|
|
666
810
|
);
|
|
667
811
|
case "categories":
|
|
668
|
-
return searchQuery ? null : /* @__PURE__ */
|
|
812
|
+
return searchQuery ? null : /* @__PURE__ */ jsx10(
|
|
669
813
|
ArticleCategoryGrid,
|
|
670
814
|
{
|
|
671
815
|
categories,
|
|
@@ -689,9 +833,9 @@ function ArticlesPage({ config }) {
|
|
|
689
833
|
const articlesWithoutFeatured = hasFeatured ? state.articles.slice(1) : state.articles;
|
|
690
834
|
const displayedArticles = state.searchQuery ? state.articles : articlesWithoutFeatured;
|
|
691
835
|
const ctx = __spreadProps(__spreadValues({}, state), { displayedArticles, pageSize, categoriesPageSize });
|
|
692
|
-
return /* @__PURE__ */
|
|
836
|
+
return /* @__PURE__ */ jsxs10("div", { style: themeVars, children: [
|
|
693
837
|
layout.map((section) => renderSection(section, ctx, config)),
|
|
694
|
-
state.articles.length > 0 && /* @__PURE__ */
|
|
838
|
+
state.articles.length > 0 && /* @__PURE__ */ jsx10(
|
|
695
839
|
CollectionPageSchema,
|
|
696
840
|
{
|
|
697
841
|
title: `Articles | ${config.siteName}`,
|
|
@@ -704,10 +848,11 @@ function ArticlesPage({ config }) {
|
|
|
704
848
|
}
|
|
705
849
|
|
|
706
850
|
// src/ArticleDetailHero.tsx
|
|
851
|
+
import { Fragment as Fragment3 } from "react";
|
|
707
852
|
import Image4 from "next/image";
|
|
708
|
-
import
|
|
853
|
+
import Link6 from "next/link";
|
|
709
854
|
import { Calendar as Calendar3, Clock as Clock3, User as User2 } from "lucide-react";
|
|
710
|
-
import { jsx as
|
|
855
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
711
856
|
function toSlug(cat) {
|
|
712
857
|
return cat.toLowerCase().replaceAll(/\s+/g, "-").replaceAll(/[^a-z0-9-]/g, "");
|
|
713
858
|
}
|
|
@@ -715,9 +860,12 @@ function ArticleDetailHero({
|
|
|
715
860
|
article,
|
|
716
861
|
categoryBasePath = "/articles/category",
|
|
717
862
|
showDate = false,
|
|
718
|
-
showAuthor = true
|
|
863
|
+
showAuthor = true,
|
|
864
|
+
authors = []
|
|
719
865
|
}) {
|
|
720
|
-
|
|
866
|
+
const showConfiguredAuthors = showAuthor && authors.length > 0;
|
|
867
|
+
const showLegacyAuthor = showAuthor && authors.length === 0 && article.author.trim().length > 0;
|
|
868
|
+
return /* @__PURE__ */ jsxs11(
|
|
721
869
|
"section",
|
|
722
870
|
{
|
|
723
871
|
style: {
|
|
@@ -729,7 +877,7 @@ function ArticleDetailHero({
|
|
|
729
877
|
overflow: "hidden"
|
|
730
878
|
},
|
|
731
879
|
children: [
|
|
732
|
-
/* @__PURE__ */
|
|
880
|
+
/* @__PURE__ */ jsx11(
|
|
733
881
|
Image4,
|
|
734
882
|
{
|
|
735
883
|
src: article.featuredImage,
|
|
@@ -741,7 +889,7 @@ function ArticleDetailHero({
|
|
|
741
889
|
priority: true
|
|
742
890
|
}
|
|
743
891
|
),
|
|
744
|
-
/* @__PURE__ */
|
|
892
|
+
/* @__PURE__ */ jsx11(
|
|
745
893
|
"div",
|
|
746
894
|
{
|
|
747
895
|
style: {
|
|
@@ -751,7 +899,7 @@ function ArticleDetailHero({
|
|
|
751
899
|
}
|
|
752
900
|
}
|
|
753
901
|
),
|
|
754
|
-
/* @__PURE__ */
|
|
902
|
+
/* @__PURE__ */ jsxs11(
|
|
755
903
|
"div",
|
|
756
904
|
{
|
|
757
905
|
style: {
|
|
@@ -765,7 +913,7 @@ function ArticleDetailHero({
|
|
|
765
913
|
width: "100%"
|
|
766
914
|
},
|
|
767
915
|
children: [
|
|
768
|
-
article.categories && article.categories.length > 0 && /* @__PURE__ */
|
|
916
|
+
article.categories && article.categories.length > 0 && /* @__PURE__ */ jsx11(
|
|
769
917
|
"div",
|
|
770
918
|
{
|
|
771
919
|
style: {
|
|
@@ -776,15 +924,15 @@ function ArticleDetailHero({
|
|
|
776
924
|
marginBottom: "1rem"
|
|
777
925
|
},
|
|
778
926
|
children: article.categories.slice(0, 4).map(
|
|
779
|
-
(cat) => categoryBasePath ? /* @__PURE__ */
|
|
780
|
-
|
|
927
|
+
(cat) => categoryBasePath ? /* @__PURE__ */ jsx11(
|
|
928
|
+
Link6,
|
|
781
929
|
{
|
|
782
930
|
href: `${categoryBasePath}/${toSlug(cat)}`,
|
|
783
931
|
className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full hover:bg-white/30 transition-colors",
|
|
784
932
|
children: cat
|
|
785
933
|
},
|
|
786
934
|
cat
|
|
787
|
-
) : /* @__PURE__ */
|
|
935
|
+
) : /* @__PURE__ */ jsx11(
|
|
788
936
|
"span",
|
|
789
937
|
{
|
|
790
938
|
className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full",
|
|
@@ -795,8 +943,8 @@ function ArticleDetailHero({
|
|
|
795
943
|
)
|
|
796
944
|
}
|
|
797
945
|
),
|
|
798
|
-
/* @__PURE__ */
|
|
799
|
-
/* @__PURE__ */
|
|
946
|
+
/* @__PURE__ */ jsx11("h1", { className: "text-4xl md:text-5xl font-bold mb-4", children: article.title }),
|
|
947
|
+
/* @__PURE__ */ jsxs11(
|
|
800
948
|
"div",
|
|
801
949
|
{
|
|
802
950
|
style: {
|
|
@@ -808,17 +956,35 @@ function ArticleDetailHero({
|
|
|
808
956
|
color: "rgba(255,255,255,0.8)"
|
|
809
957
|
},
|
|
810
958
|
children: [
|
|
811
|
-
showDate && article.date && /* @__PURE__ */
|
|
812
|
-
/* @__PURE__ */
|
|
813
|
-
/* @__PURE__ */
|
|
959
|
+
showDate && article.date && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
960
|
+
/* @__PURE__ */ jsx11(Calendar3, { className: "h-4 w-4" }),
|
|
961
|
+
/* @__PURE__ */ jsx11("span", { children: article.date })
|
|
962
|
+
] }),
|
|
963
|
+
/* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
964
|
+
/* @__PURE__ */ jsx11(Clock3, { className: "h-4 w-4" }),
|
|
965
|
+
/* @__PURE__ */ jsx11("span", { children: article.readTime })
|
|
814
966
|
] }),
|
|
815
|
-
/* @__PURE__ */
|
|
816
|
-
/* @__PURE__ */
|
|
817
|
-
/* @__PURE__ */
|
|
967
|
+
showConfiguredAuthors && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
968
|
+
/* @__PURE__ */ jsx11(User2, { className: "h-4 w-4" }),
|
|
969
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
970
|
+
"By",
|
|
971
|
+
" ",
|
|
972
|
+
authors.map((author, index) => /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
973
|
+
index > 0 && ", ",
|
|
974
|
+
/* @__PURE__ */ jsx11(
|
|
975
|
+
Link6,
|
|
976
|
+
{
|
|
977
|
+
href: `/articles/authors/${author.slug}`,
|
|
978
|
+
className: "font-medium text-white underline-offset-4 hover:underline",
|
|
979
|
+
children: author.name
|
|
980
|
+
}
|
|
981
|
+
)
|
|
982
|
+
] }, author.slug))
|
|
983
|
+
] })
|
|
818
984
|
] }),
|
|
819
|
-
|
|
820
|
-
/* @__PURE__ */
|
|
821
|
-
/* @__PURE__ */
|
|
985
|
+
showLegacyAuthor && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
986
|
+
/* @__PURE__ */ jsx11(User2, { className: "h-4 w-4" }),
|
|
987
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
822
988
|
"By ",
|
|
823
989
|
article.author
|
|
824
990
|
] })
|
|
@@ -836,8 +1002,8 @@ function ArticleDetailHero({
|
|
|
836
1002
|
|
|
837
1003
|
// src/CategoryArticlesPage.tsx
|
|
838
1004
|
import Image5 from "next/image";
|
|
839
|
-
import
|
|
840
|
-
import { jsx as
|
|
1005
|
+
import Link7 from "next/link";
|
|
1006
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
841
1007
|
function getCategoryDescription(config, slug, categoryName) {
|
|
842
1008
|
var _a;
|
|
843
1009
|
const raw = (_a = config.categoryDescriptions) == null ? void 0 : _a[slug];
|
|
@@ -845,6 +1011,40 @@ function getCategoryDescription(config, slug, categoryName) {
|
|
|
845
1011
|
if (typeof raw === "string") return { short: raw };
|
|
846
1012
|
return raw;
|
|
847
1013
|
}
|
|
1014
|
+
function buildCategoryBreadcrumbItems(config, categoryName) {
|
|
1015
|
+
var _a;
|
|
1016
|
+
const siteUrl = config.siteUrl.replace(/\/$/, "");
|
|
1017
|
+
const breadcrumbConfig = getBreadcrumbsConfig(config);
|
|
1018
|
+
const trail = (_a = breadcrumbConfig.category) != null ? _a : ["home", "articles", "category"];
|
|
1019
|
+
return trail.flatMap(
|
|
1020
|
+
(entry) => {
|
|
1021
|
+
var _a2;
|
|
1022
|
+
return buildCategoryBreadcrumbEntry(entry, {
|
|
1023
|
+
categoryName,
|
|
1024
|
+
siteUrl,
|
|
1025
|
+
labels: (_a2 = breadcrumbConfig.labels) != null ? _a2 : {}
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
function isCustomBreadcrumbItem(entry) {
|
|
1031
|
+
return typeof entry === "object" && entry !== null && "name" in entry && "url" in entry;
|
|
1032
|
+
}
|
|
1033
|
+
function resolveCustomBreadcrumbItem(item, siteUrl) {
|
|
1034
|
+
if (item.url.startsWith("/")) return { name: item.name, url: `${siteUrl}${item.url}` };
|
|
1035
|
+
return { name: item.name, url: item.url };
|
|
1036
|
+
}
|
|
1037
|
+
function buildCategoryBreadcrumbEntry(entry, context) {
|
|
1038
|
+
var _a, _b;
|
|
1039
|
+
if (isCustomBreadcrumbItem(entry)) {
|
|
1040
|
+
return [resolveCustomBreadcrumbItem(entry, context.siteUrl)];
|
|
1041
|
+
}
|
|
1042
|
+
if (entry === "home") return [{ name: (_a = context.labels.home) != null ? _a : "Home", url: context.siteUrl }];
|
|
1043
|
+
if (entry === "articles") {
|
|
1044
|
+
return [{ name: (_b = context.labels.articles) != null ? _b : "Articles", url: `${context.siteUrl}/articles` }];
|
|
1045
|
+
}
|
|
1046
|
+
return [{ name: context.categoryName }];
|
|
1047
|
+
}
|
|
848
1048
|
function CategoryArticlesPage({ category, articles, config }) {
|
|
849
1049
|
var _a;
|
|
850
1050
|
if (articles.length === 0) return null;
|
|
@@ -852,19 +1052,18 @@ function CategoryArticlesPage({ category, articles, config }) {
|
|
|
852
1052
|
const heroImage = articles[0].featuredImage;
|
|
853
1053
|
const description = getCategoryDescription(config, category, categoryName);
|
|
854
1054
|
const pageSize = (_a = config.pageSize) != null ? _a : DEFAULT_PAGE_SIZE;
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
1055
|
+
const breadcrumbConfig = getBreadcrumbsConfig(config);
|
|
1056
|
+
const breadcrumbItems = buildCategoryBreadcrumbItems(config, categoryName);
|
|
1057
|
+
return /* @__PURE__ */ jsxs12("div", { children: [
|
|
1058
|
+
breadcrumbsAreEnabled(config) && /* @__PURE__ */ jsx12(
|
|
1059
|
+
Breadcrumb,
|
|
859
1060
|
{
|
|
860
|
-
items:
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
{ name: categoryName, url: `${siteUrl}/articles/category/${category}` }
|
|
864
|
-
]
|
|
1061
|
+
items: breadcrumbItems,
|
|
1062
|
+
separator: breadcrumbConfig.separator,
|
|
1063
|
+
showSchema: breadcrumbConfig.showSchema !== false
|
|
865
1064
|
}
|
|
866
1065
|
),
|
|
867
|
-
/* @__PURE__ */
|
|
1066
|
+
/* @__PURE__ */ jsxs12(
|
|
868
1067
|
"section",
|
|
869
1068
|
{
|
|
870
1069
|
style: {
|
|
@@ -876,7 +1075,7 @@ function CategoryArticlesPage({ category, articles, config }) {
|
|
|
876
1075
|
overflow: "hidden"
|
|
877
1076
|
},
|
|
878
1077
|
children: [
|
|
879
|
-
/* @__PURE__ */
|
|
1078
|
+
/* @__PURE__ */ jsx12(
|
|
880
1079
|
Image5,
|
|
881
1080
|
{
|
|
882
1081
|
src: heroImage,
|
|
@@ -887,8 +1086,8 @@ function CategoryArticlesPage({ category, articles, config }) {
|
|
|
887
1086
|
priority: true
|
|
888
1087
|
}
|
|
889
1088
|
),
|
|
890
|
-
/* @__PURE__ */
|
|
891
|
-
/* @__PURE__ */
|
|
1089
|
+
/* @__PURE__ */ jsx12("div", { style: { position: "absolute", inset: 0, backgroundColor: "rgba(0,0,0,0.6)" } }),
|
|
1090
|
+
/* @__PURE__ */ jsxs12(
|
|
892
1091
|
"div",
|
|
893
1092
|
{
|
|
894
1093
|
style: {
|
|
@@ -899,10 +1098,10 @@ function CategoryArticlesPage({ category, articles, config }) {
|
|
|
899
1098
|
padding: "0 1rem"
|
|
900
1099
|
},
|
|
901
1100
|
children: [
|
|
902
|
-
/* @__PURE__ */
|
|
903
|
-
/* @__PURE__ */
|
|
904
|
-
description.long && /* @__PURE__ */
|
|
905
|
-
/* @__PURE__ */
|
|
1101
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm font-semibold uppercase tracking-widest mb-3 opacity-80", children: "Category" }),
|
|
1102
|
+
/* @__PURE__ */ jsx12("h1", { className: "text-4xl md:text-5xl font-bold mb-3", children: categoryName }),
|
|
1103
|
+
description.long && /* @__PURE__ */ jsx12("p", { className: "text-lg opacity-90 max-w-2xl mx-auto mt-2", children: description.long }),
|
|
1104
|
+
/* @__PURE__ */ jsxs12("p", { className: "text-lg opacity-70 mt-2", children: [
|
|
906
1105
|
articles.length,
|
|
907
1106
|
" article",
|
|
908
1107
|
articles.length === 1 ? "" : "s"
|
|
@@ -913,20 +1112,178 @@ function CategoryArticlesPage({ category, articles, config }) {
|
|
|
913
1112
|
]
|
|
914
1113
|
}
|
|
915
1114
|
),
|
|
916
|
-
/* @__PURE__ */
|
|
917
|
-
/* @__PURE__ */
|
|
918
|
-
/* @__PURE__ */
|
|
919
|
-
/* @__PURE__ */
|
|
1115
|
+
/* @__PURE__ */ jsx12("section", { className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsxs12("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
|
|
1116
|
+
/* @__PURE__ */ jsxs12("div", { className: "mb-8 flex items-center justify-between", children: [
|
|
1117
|
+
/* @__PURE__ */ jsx12(Link7, { href: "/articles", className: "text-sm text-primary hover:underline", children: "\u2190 All Articles" }),
|
|
1118
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: description.short })
|
|
920
1119
|
] }),
|
|
921
|
-
/* @__PURE__ */
|
|
1120
|
+
/* @__PURE__ */ jsx12(LatestArticles, { articles, pageSize })
|
|
922
1121
|
] }) })
|
|
923
1122
|
] });
|
|
924
1123
|
}
|
|
925
1124
|
|
|
1125
|
+
// src/AuthorArticlesPage.tsx
|
|
1126
|
+
import Link8 from "next/link";
|
|
1127
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1128
|
+
function getPersonSchema(author, config, articleCount) {
|
|
1129
|
+
var _a, _b;
|
|
1130
|
+
return __spreadProps(__spreadValues(__spreadValues({
|
|
1131
|
+
"@context": "https://schema.org",
|
|
1132
|
+
"@type": "Person",
|
|
1133
|
+
name: author.name,
|
|
1134
|
+
description: author.bio,
|
|
1135
|
+
url: (_a = author.url) != null ? _a : getAuthorUrl(author)
|
|
1136
|
+
}, getAuthorAvatar(author, config) && { image: getAuthorAvatar(author, config) }), getAuthorSameAs(author).length > 0 && { sameAs: getAuthorSameAs(author) }), {
|
|
1137
|
+
knowsAbout: config.siteName,
|
|
1138
|
+
mainEntityOfPage: (_b = author.url) != null ? _b : `${config.siteUrl.replace(/\/$/, "")}/articles/authors/${author.slug}`,
|
|
1139
|
+
interactionStatistic: {
|
|
1140
|
+
"@type": "InteractionCounter",
|
|
1141
|
+
interactionType: "https://schema.org/WriteAction",
|
|
1142
|
+
userInteractionCount: articleCount
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
function AuthorArticlesPage({ author, articles, config }) {
|
|
1147
|
+
var _a;
|
|
1148
|
+
const pageSize = (_a = config.pageSize) != null ? _a : DEFAULT_PAGE_SIZE;
|
|
1149
|
+
return /* @__PURE__ */ jsxs13("div", { children: [
|
|
1150
|
+
/* @__PURE__ */ jsx13(
|
|
1151
|
+
"script",
|
|
1152
|
+
{
|
|
1153
|
+
type: "application/ld+json",
|
|
1154
|
+
dangerouslySetInnerHTML: {
|
|
1155
|
+
__html: JSON.stringify(getPersonSchema(author, config, articles.length))
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
),
|
|
1159
|
+
/* @__PURE__ */ jsx13("section", { className: "bg-background py-16", children: /* @__PURE__ */ jsxs13("div", { className: "mx-auto max-w-7xl px-4 sm:px-6 lg:px-8", children: [
|
|
1160
|
+
/* @__PURE__ */ jsxs13("div", { className: "mb-8 flex items-center justify-between gap-4", children: [
|
|
1161
|
+
/* @__PURE__ */ jsx13(Link8, { href: "/articles", className: "text-sm text-primary hover:underline", children: "All Articles" }),
|
|
1162
|
+
/* @__PURE__ */ jsxs13("p", { className: "text-sm text-muted-foreground", children: [
|
|
1163
|
+
"Articles by ",
|
|
1164
|
+
author.name
|
|
1165
|
+
] })
|
|
1166
|
+
] }),
|
|
1167
|
+
/* @__PURE__ */ jsx13(LatestArticles, { articles, pageSize })
|
|
1168
|
+
] }) })
|
|
1169
|
+
] });
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
// src/AuthorCard.tsx
|
|
1173
|
+
import Image6 from "next/image";
|
|
1174
|
+
import Link9 from "next/link";
|
|
1175
|
+
import {
|
|
1176
|
+
Facebook,
|
|
1177
|
+
Github,
|
|
1178
|
+
Globe,
|
|
1179
|
+
Instagram,
|
|
1180
|
+
Linkedin,
|
|
1181
|
+
Mail,
|
|
1182
|
+
MessageCircle,
|
|
1183
|
+
Twitter,
|
|
1184
|
+
Youtube
|
|
1185
|
+
} from "lucide-react";
|
|
1186
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1187
|
+
function getInitials(name) {
|
|
1188
|
+
return name.split(" ").filter(Boolean).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
|
|
1189
|
+
}
|
|
1190
|
+
function AuthorCard({
|
|
1191
|
+
author,
|
|
1192
|
+
linkToPage = true,
|
|
1193
|
+
showBio = false,
|
|
1194
|
+
showSocial = false
|
|
1195
|
+
}) {
|
|
1196
|
+
const avatar = getAuthorAvatar(author);
|
|
1197
|
+
const name = linkToPage ? /* @__PURE__ */ jsx14(Link9, { href: getAuthorUrl(author), className: "font-medium text-foreground hover:text-primary", children: author.name }) : /* @__PURE__ */ jsx14("span", { className: "font-medium text-foreground", children: author.name });
|
|
1198
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 rounded-lg border border-border bg-card p-4 text-card-foreground", children: [
|
|
1199
|
+
avatar ? /* @__PURE__ */ jsx14(
|
|
1200
|
+
Image6,
|
|
1201
|
+
{
|
|
1202
|
+
src: avatar,
|
|
1203
|
+
alt: author.name,
|
|
1204
|
+
width: 48,
|
|
1205
|
+
height: 48,
|
|
1206
|
+
className: "h-12 w-12 rounded-full object-cover"
|
|
1207
|
+
}
|
|
1208
|
+
) : /* @__PURE__ */ jsx14("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-muted text-sm font-semibold text-muted-foreground", children: getInitials(author.name) }),
|
|
1209
|
+
/* @__PURE__ */ jsxs14("div", { className: "min-w-0 flex-1", children: [
|
|
1210
|
+
name,
|
|
1211
|
+
showBio && author.bio && /* @__PURE__ */ jsx14("p", { className: "mt-1 line-clamp-2 text-sm text-muted-foreground", children: author.bio }),
|
|
1212
|
+
showSocial && /* @__PURE__ */ jsx14(AuthorSocialLinks, { author })
|
|
1213
|
+
] })
|
|
1214
|
+
] });
|
|
1215
|
+
}
|
|
1216
|
+
var SOCIAL_ICONS = {
|
|
1217
|
+
Website: Globe,
|
|
1218
|
+
Facebook,
|
|
1219
|
+
Twitter,
|
|
1220
|
+
X: Twitter,
|
|
1221
|
+
LinkedIn: Linkedin,
|
|
1222
|
+
Instagram,
|
|
1223
|
+
YouTube: Youtube,
|
|
1224
|
+
GitHub: Github,
|
|
1225
|
+
Newsletter: Mail
|
|
1226
|
+
};
|
|
1227
|
+
function getSocialIcon(label) {
|
|
1228
|
+
var _a;
|
|
1229
|
+
return (_a = SOCIAL_ICONS[label]) != null ? _a : MessageCircle;
|
|
1230
|
+
}
|
|
1231
|
+
function AuthorSocialLinks({ author }) {
|
|
1232
|
+
const links = getAuthorSocialLinks(author);
|
|
1233
|
+
if (links.length === 0) return null;
|
|
1234
|
+
return /* @__PURE__ */ jsx14("div", { className: "mt-3 flex items-center gap-2", children: links.map(({ href, label }) => {
|
|
1235
|
+
const Icon = getSocialIcon(label);
|
|
1236
|
+
return /* @__PURE__ */ jsx14(
|
|
1237
|
+
Link9,
|
|
1238
|
+
{
|
|
1239
|
+
href,
|
|
1240
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
1241
|
+
"aria-label": `${author.name} on ${label}`,
|
|
1242
|
+
children: /* @__PURE__ */ jsx14(Icon, { className: "h-4 w-4" })
|
|
1243
|
+
},
|
|
1244
|
+
`${label}-${href}`
|
|
1245
|
+
);
|
|
1246
|
+
}) });
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/AuthorDetailHero.tsx
|
|
1250
|
+
import Image7 from "next/image";
|
|
1251
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1252
|
+
function getInitials2(name) {
|
|
1253
|
+
return name.split(" ").filter(Boolean).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
|
|
1254
|
+
}
|
|
1255
|
+
function AuthorDetailHero({ author, articleCount }) {
|
|
1256
|
+
const avatar = getAuthorAvatar(author);
|
|
1257
|
+
return /* @__PURE__ */ jsx15("section", { className: "bg-muted/40 py-16", children: /* @__PURE__ */ jsxs15("div", { className: "mx-auto flex max-w-4xl flex-col items-center gap-6 px-4 text-center sm:px-6 lg:px-8", children: [
|
|
1258
|
+
avatar ? /* @__PURE__ */ jsx15(
|
|
1259
|
+
Image7,
|
|
1260
|
+
{
|
|
1261
|
+
src: avatar,
|
|
1262
|
+
alt: author.name,
|
|
1263
|
+
width: 120,
|
|
1264
|
+
height: 120,
|
|
1265
|
+
className: "h-28 w-28 rounded-full object-cover",
|
|
1266
|
+
priority: true
|
|
1267
|
+
}
|
|
1268
|
+
) : /* @__PURE__ */ jsx15("div", { className: "flex h-28 w-28 items-center justify-center rounded-full bg-card text-3xl font-semibold text-muted-foreground shadow-sm", children: getInitials2(author.name) }),
|
|
1269
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
1270
|
+
/* @__PURE__ */ jsx15("p", { className: "mb-3 text-sm font-semibold uppercase tracking-widest text-muted-foreground", children: "Author" }),
|
|
1271
|
+
/* @__PURE__ */ jsx15("h1", { className: "text-4xl font-bold text-foreground md:text-5xl", children: author.name }),
|
|
1272
|
+
/* @__PURE__ */ jsx15("p", { className: "mx-auto mt-4 max-w-2xl text-lg text-muted-foreground", children: author.bio }),
|
|
1273
|
+
typeof articleCount === "number" && /* @__PURE__ */ jsxs15("p", { className: "mt-3 text-sm text-muted-foreground", children: [
|
|
1274
|
+
articleCount,
|
|
1275
|
+
" article",
|
|
1276
|
+
articleCount === 1 ? "" : "s"
|
|
1277
|
+
] })
|
|
1278
|
+
] }),
|
|
1279
|
+
/* @__PURE__ */ jsx15(AuthorSocialLinks, { author })
|
|
1280
|
+
] }) });
|
|
1281
|
+
}
|
|
1282
|
+
|
|
926
1283
|
// src/ArticleSocialShare.tsx
|
|
927
1284
|
import { useState as useState4 } from "react";
|
|
928
|
-
import { Share2, Copy, Check, Mail, MessageCircle, Users, FileText } from "lucide-react";
|
|
929
|
-
import { jsx as
|
|
1285
|
+
import { Share2, Copy, Check, Mail as Mail2, MessageCircle as MessageCircle2, Users, FileText } from "lucide-react";
|
|
1286
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
930
1287
|
function ArticleSocialShare({ title, url, excerpt, shareMessage }) {
|
|
931
1288
|
const [copied, setCopied] = useState4(false);
|
|
932
1289
|
const encodedTitle = encodeURIComponent(title);
|
|
@@ -953,84 +1310,84 @@ function ArticleSocialShare({ title, url, excerpt, shareMessage }) {
|
|
|
953
1310
|
globalThis.open(shareUrl, "_blank", "width=600,height=400,scrollbars=yes,resizable=yes");
|
|
954
1311
|
};
|
|
955
1312
|
const btnClass = "inline-flex items-center gap-2 px-3 py-1.5 text-sm rounded-md border border-border bg-background text-foreground hover:bg-primary/10 hover:border-primary hover:text-primary transition-colors cursor-pointer";
|
|
956
|
-
return /* @__PURE__ */
|
|
957
|
-
/* @__PURE__ */
|
|
958
|
-
/* @__PURE__ */
|
|
959
|
-
/* @__PURE__ */
|
|
1313
|
+
return /* @__PURE__ */ jsxs16("div", { className: "border-t border-border pt-8 mt-8", children: [
|
|
1314
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 mb-4", children: [
|
|
1315
|
+
/* @__PURE__ */ jsx16(Share2, { className: "h-5 w-5 text-muted-foreground" }),
|
|
1316
|
+
/* @__PURE__ */ jsx16("h3", { className: "text-lg font-semibold text-foreground", children: "Share this article" })
|
|
960
1317
|
] }),
|
|
961
|
-
/* @__PURE__ */
|
|
962
|
-
/* @__PURE__ */
|
|
963
|
-
/* @__PURE__ */
|
|
1318
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-wrap gap-2", children: [
|
|
1319
|
+
/* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.linkedin), children: [
|
|
1320
|
+
/* @__PURE__ */ jsx16(Users, { className: "h-4 w-4" }),
|
|
964
1321
|
"LinkedIn"
|
|
965
1322
|
] }),
|
|
966
|
-
/* @__PURE__ */
|
|
967
|
-
/* @__PURE__ */
|
|
1323
|
+
/* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.facebook), children: [
|
|
1324
|
+
/* @__PURE__ */ jsx16("span", { className: "text-xs font-bold", children: "f" }),
|
|
968
1325
|
" Facebook"
|
|
969
1326
|
] }),
|
|
970
|
-
/* @__PURE__ */
|
|
971
|
-
/* @__PURE__ */
|
|
1327
|
+
/* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.twitter), children: [
|
|
1328
|
+
/* @__PURE__ */ jsx16(MessageCircle2, { className: "h-4 w-4" }),
|
|
972
1329
|
"Twitter"
|
|
973
1330
|
] }),
|
|
974
|
-
/* @__PURE__ */
|
|
975
|
-
/* @__PURE__ */
|
|
1331
|
+
/* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.reddit), children: [
|
|
1332
|
+
/* @__PURE__ */ jsx16(FileText, { className: "h-4 w-4" }),
|
|
976
1333
|
"Reddit"
|
|
977
1334
|
] }),
|
|
978
|
-
/* @__PURE__ */
|
|
979
|
-
/* @__PURE__ */
|
|
1335
|
+
/* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.whatsapp), children: [
|
|
1336
|
+
/* @__PURE__ */ jsx16(MessageCircle2, { className: "h-4 w-4" }),
|
|
980
1337
|
"WhatsApp"
|
|
981
1338
|
] }),
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
1339
|
+
/* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.telegram), children: [
|
|
1340
|
+
/* @__PURE__ */ jsx16(MessageCircle2, { className: "h-4 w-4" }),
|
|
984
1341
|
"Telegram"
|
|
985
1342
|
] }),
|
|
986
|
-
/* @__PURE__ */
|
|
987
|
-
/* @__PURE__ */
|
|
1343
|
+
/* @__PURE__ */ jsxs16("a", { className: btnClass, href: shareLinks.email, children: [
|
|
1344
|
+
/* @__PURE__ */ jsx16(Mail2, { className: "h-4 w-4" }),
|
|
988
1345
|
"Email"
|
|
989
1346
|
] }),
|
|
990
|
-
/* @__PURE__ */
|
|
991
|
-
copied ? /* @__PURE__ */
|
|
1347
|
+
/* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: copyToClipboard, children: [
|
|
1348
|
+
copied ? /* @__PURE__ */ jsx16(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx16(Copy, { className: "h-4 w-4" }),
|
|
992
1349
|
copied ? "Copied!" : "Copy Link"
|
|
993
1350
|
] })
|
|
994
1351
|
] }),
|
|
995
|
-
shareMessage && /* @__PURE__ */
|
|
1352
|
+
shareMessage && /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground mt-3", children: shareMessage })
|
|
996
1353
|
] });
|
|
997
1354
|
}
|
|
998
1355
|
|
|
999
1356
|
// src/ArticleNavigation.tsx
|
|
1000
|
-
import
|
|
1357
|
+
import Link10 from "next/link";
|
|
1001
1358
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
1002
|
-
import { jsx as
|
|
1359
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1003
1360
|
function truncateTitle(title, maxLength = 60) {
|
|
1004
1361
|
return title.length > maxLength ? `${title.substring(0, maxLength)}...` : title;
|
|
1005
1362
|
}
|
|
1006
1363
|
function ArticleNavigation({ previous, next, basePath }) {
|
|
1007
1364
|
if (!previous && !next) return null;
|
|
1008
|
-
return /* @__PURE__ */
|
|
1009
|
-
/* @__PURE__ */
|
|
1010
|
-
|
|
1365
|
+
return /* @__PURE__ */ jsx17("nav", { className: "mt-12 pt-8 border-t border-border", "aria-label": "Article navigation", children: /* @__PURE__ */ jsxs17("div", { className: "flex justify-between gap-4", children: [
|
|
1366
|
+
/* @__PURE__ */ jsx17("div", { className: "flex-1 min-w-0", children: previous && /* @__PURE__ */ jsxs17(
|
|
1367
|
+
Link10,
|
|
1011
1368
|
{
|
|
1012
1369
|
href: `${basePath}/${previous.slug}`,
|
|
1013
1370
|
className: "group flex items-center gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors",
|
|
1014
1371
|
children: [
|
|
1015
|
-
/* @__PURE__ */
|
|
1016
|
-
/* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1372
|
+
/* @__PURE__ */ jsx17(ChevronLeft, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" }),
|
|
1373
|
+
/* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
|
|
1374
|
+
/* @__PURE__ */ jsx17("div", { className: "text-sm text-muted-foreground mb-1", children: "Previous Article" }),
|
|
1375
|
+
/* @__PURE__ */ jsx17("div", { className: "font-medium text-foreground truncate", title: previous.title, children: truncateTitle(previous.title) })
|
|
1019
1376
|
] })
|
|
1020
1377
|
]
|
|
1021
1378
|
}
|
|
1022
1379
|
) }),
|
|
1023
|
-
/* @__PURE__ */
|
|
1024
|
-
|
|
1380
|
+
/* @__PURE__ */ jsx17("div", { className: "flex-1 min-w-0", children: next && /* @__PURE__ */ jsxs17(
|
|
1381
|
+
Link10,
|
|
1025
1382
|
{
|
|
1026
1383
|
href: `${basePath}/${next.slug}`,
|
|
1027
1384
|
className: "group flex items-center justify-end gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors",
|
|
1028
1385
|
children: [
|
|
1029
|
-
/* @__PURE__ */
|
|
1030
|
-
/* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1386
|
+
/* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1 text-right", children: [
|
|
1387
|
+
/* @__PURE__ */ jsx17("div", { className: "text-sm text-muted-foreground mb-1", children: "Next Article" }),
|
|
1388
|
+
/* @__PURE__ */ jsx17("div", { className: "font-medium text-foreground truncate", title: next.title, children: truncateTitle(next.title) })
|
|
1032
1389
|
] }),
|
|
1033
|
-
/* @__PURE__ */
|
|
1390
|
+
/* @__PURE__ */ jsx17(ChevronRight, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" })
|
|
1034
1391
|
]
|
|
1035
1392
|
}
|
|
1036
1393
|
) })
|
|
@@ -1038,9 +1395,9 @@ function ArticleNavigation({ previous, next, basePath }) {
|
|
|
1038
1395
|
}
|
|
1039
1396
|
|
|
1040
1397
|
// src/ArticleBackLink.tsx
|
|
1041
|
-
import
|
|
1398
|
+
import Link11 from "next/link";
|
|
1042
1399
|
import { ArrowLeft } from "lucide-react";
|
|
1043
|
-
import { jsx as
|
|
1400
|
+
import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1044
1401
|
function ArticleBackLink({
|
|
1045
1402
|
config,
|
|
1046
1403
|
href = "/articles",
|
|
@@ -1048,13 +1405,13 @@ function ArticleBackLink({
|
|
|
1048
1405
|
className
|
|
1049
1406
|
}) {
|
|
1050
1407
|
if (config.showBackToArticles === false) return null;
|
|
1051
|
-
return /* @__PURE__ */
|
|
1052
|
-
|
|
1408
|
+
return /* @__PURE__ */ jsxs18(
|
|
1409
|
+
Link11,
|
|
1053
1410
|
{
|
|
1054
1411
|
href,
|
|
1055
1412
|
className: className != null ? className : "inline-flex items-center gap-2 mb-6 -ml-3 px-3 py-2 rounded-md text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
|
|
1056
1413
|
children: [
|
|
1057
|
-
/* @__PURE__ */
|
|
1414
|
+
/* @__PURE__ */ jsx18(ArrowLeft, { className: "h-4 w-4" }),
|
|
1058
1415
|
label
|
|
1059
1416
|
]
|
|
1060
1417
|
}
|
|
@@ -1062,17 +1419,17 @@ function ArticleBackLink({
|
|
|
1062
1419
|
}
|
|
1063
1420
|
|
|
1064
1421
|
// src/ArticleTOC.tsx
|
|
1065
|
-
import { jsx as
|
|
1422
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1066
1423
|
function ArticleTOC({ toc, className }) {
|
|
1067
1424
|
if (!toc.length) return null;
|
|
1068
|
-
return /* @__PURE__ */
|
|
1425
|
+
return /* @__PURE__ */ jsxs19(
|
|
1069
1426
|
"nav",
|
|
1070
1427
|
{
|
|
1071
1428
|
"aria-label": "Table of contents",
|
|
1072
1429
|
className: `mb-8 rounded-lg border border-border bg-muted/40 px-6 py-4 ${className != null ? className : ""}`,
|
|
1073
1430
|
children: [
|
|
1074
|
-
/* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
1431
|
+
/* @__PURE__ */ jsx19("p", { className: "mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground", children: "On this page" }),
|
|
1432
|
+
/* @__PURE__ */ jsx19("ul", { className: "space-y-1 text-sm", children: toc.map((item) => /* @__PURE__ */ jsx19("li", { style: { paddingLeft: `${Math.max(0, item.depth - 2) * 1}rem` }, children: /* @__PURE__ */ jsx19(
|
|
1076
1433
|
"a",
|
|
1077
1434
|
{
|
|
1078
1435
|
href: `#${item.id}`,
|
|
@@ -1088,7 +1445,7 @@ function ArticleTOC({ toc, className }) {
|
|
|
1088
1445
|
// src/ScrollToTop.tsx
|
|
1089
1446
|
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
1090
1447
|
import { ArrowUp } from "lucide-react";
|
|
1091
|
-
import { jsx as
|
|
1448
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1092
1449
|
function ScrollToTop() {
|
|
1093
1450
|
const [visible, setVisible] = useState5(false);
|
|
1094
1451
|
useEffect4(() => {
|
|
@@ -1097,13 +1454,13 @@ function ScrollToTop() {
|
|
|
1097
1454
|
return () => globalThis.removeEventListener("scroll", onScroll);
|
|
1098
1455
|
}, []);
|
|
1099
1456
|
if (!visible) return null;
|
|
1100
|
-
return /* @__PURE__ */
|
|
1457
|
+
return /* @__PURE__ */ jsx20(
|
|
1101
1458
|
"button",
|
|
1102
1459
|
{
|
|
1103
1460
|
"aria-label": "Scroll to top",
|
|
1104
1461
|
onClick: () => globalThis.scrollTo({ top: 0, behavior: "smooth" }),
|
|
1105
1462
|
className: "fixed bottom-8 right-8 z-50 rounded-full bg-primary p-2 shadow-md text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
1106
|
-
children: /* @__PURE__ */
|
|
1463
|
+
children: /* @__PURE__ */ jsx20(ArrowUp, { className: "h-5 w-5" })
|
|
1107
1464
|
}
|
|
1108
1465
|
);
|
|
1109
1466
|
}
|
|
@@ -1114,7 +1471,7 @@ import { useCallback as useCallback2, useEffect as useEffect5, useState as useSt
|
|
|
1114
1471
|
|
|
1115
1472
|
// src/CommentForm.tsx
|
|
1116
1473
|
import { useState as useState6 } from "react";
|
|
1117
|
-
import { jsx as
|
|
1474
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1118
1475
|
var MAX_LENGTH = 2e3;
|
|
1119
1476
|
var WARN_THRESHOLD = 1800;
|
|
1120
1477
|
function submitLabel(submitting, parentId) {
|
|
@@ -1153,8 +1510,8 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
1153
1510
|
}
|
|
1154
1511
|
});
|
|
1155
1512
|
}
|
|
1156
|
-
return /* @__PURE__ */
|
|
1157
|
-
/* @__PURE__ */
|
|
1513
|
+
return /* @__PURE__ */ jsxs20("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
|
|
1514
|
+
/* @__PURE__ */ jsx21(
|
|
1158
1515
|
"textarea",
|
|
1159
1516
|
{
|
|
1160
1517
|
value: body,
|
|
@@ -1167,13 +1524,13 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
1167
1524
|
"aria-label": parentId ? "Reply text" : "Comment text"
|
|
1168
1525
|
}
|
|
1169
1526
|
),
|
|
1170
|
-
remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */
|
|
1527
|
+
remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */ jsxs20("p", { className: `text-xs ${remaining < 0 ? "text-destructive" : "text-muted-foreground"}`, children: [
|
|
1171
1528
|
remaining,
|
|
1172
1529
|
" characters remaining"
|
|
1173
1530
|
] }),
|
|
1174
|
-
error && /* @__PURE__ */
|
|
1175
|
-
/* @__PURE__ */
|
|
1176
|
-
/* @__PURE__ */
|
|
1531
|
+
error && /* @__PURE__ */ jsx21("p", { className: "text-xs text-destructive", children: error }),
|
|
1532
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex gap-2", children: [
|
|
1533
|
+
/* @__PURE__ */ jsx21(
|
|
1177
1534
|
"button",
|
|
1178
1535
|
{
|
|
1179
1536
|
type: "submit",
|
|
@@ -1182,7 +1539,7 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
1182
1539
|
children: submitLabel(submitting, parentId)
|
|
1183
1540
|
}
|
|
1184
1541
|
),
|
|
1185
|
-
onCancel && /* @__PURE__ */
|
|
1542
|
+
onCancel && /* @__PURE__ */ jsx21(
|
|
1186
1543
|
"button",
|
|
1187
1544
|
{
|
|
1188
1545
|
type: "button",
|
|
@@ -1197,7 +1554,7 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
1197
1554
|
|
|
1198
1555
|
// src/CommentItem.tsx
|
|
1199
1556
|
import { useState as useState7 } from "react";
|
|
1200
|
-
import { Fragment as
|
|
1557
|
+
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1201
1558
|
function relativeTime(iso) {
|
|
1202
1559
|
const diff = Date.now() - new Date(iso).getTime();
|
|
1203
1560
|
const minutes = Math.floor(diff / 6e4);
|
|
@@ -1235,15 +1592,15 @@ function CommentItem({
|
|
|
1235
1592
|
}
|
|
1236
1593
|
});
|
|
1237
1594
|
}
|
|
1238
|
-
return /* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
/* @__PURE__ */
|
|
1242
|
-
/* @__PURE__ */
|
|
1595
|
+
return /* @__PURE__ */ jsxs21("div", { className: `${isReply ? "ml-8 border-l-2 border-border pl-4" : ""}`, children: [
|
|
1596
|
+
/* @__PURE__ */ jsx22("div", { className: "rounded-lg bg-muted/40 p-3 space-y-1", children: comment.isDeleted ? /* @__PURE__ */ jsx22("p", { className: "text-sm italic text-muted-foreground", children: "Comment removed" }) : /* @__PURE__ */ jsxs21(Fragment4, { children: [
|
|
1597
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1598
|
+
/* @__PURE__ */ jsx22("span", { className: "text-sm font-medium text-foreground", children: comment.authorName }),
|
|
1599
|
+
/* @__PURE__ */ jsx22("span", { className: "text-xs text-muted-foreground", children: relativeTime(comment.createdAt) })
|
|
1243
1600
|
] }),
|
|
1244
|
-
/* @__PURE__ */
|
|
1245
|
-
/* @__PURE__ */
|
|
1246
|
-
canReply && /* @__PURE__ */
|
|
1601
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm text-foreground whitespace-pre-wrap break-words", children: comment.body }),
|
|
1602
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex gap-3 pt-1", children: [
|
|
1603
|
+
canReply && /* @__PURE__ */ jsx22(
|
|
1247
1604
|
"button",
|
|
1248
1605
|
{
|
|
1249
1606
|
onClick: () => setShowReplyForm((v) => !v),
|
|
@@ -1251,7 +1608,7 @@ function CommentItem({
|
|
|
1251
1608
|
children: showReplyForm ? "Cancel" : "Reply"
|
|
1252
1609
|
}
|
|
1253
1610
|
),
|
|
1254
|
-
canDelete && /* @__PURE__ */
|
|
1611
|
+
canDelete && /* @__PURE__ */ jsx22(
|
|
1255
1612
|
"button",
|
|
1256
1613
|
{
|
|
1257
1614
|
onClick: handleDelete,
|
|
@@ -1262,7 +1619,7 @@ function CommentItem({
|
|
|
1262
1619
|
)
|
|
1263
1620
|
] })
|
|
1264
1621
|
] }) }),
|
|
1265
|
-
showReplyForm && /* @__PURE__ */
|
|
1622
|
+
showReplyForm && /* @__PURE__ */ jsx22("div", { className: "mt-2 ml-2", children: /* @__PURE__ */ jsx22(
|
|
1266
1623
|
CommentForm,
|
|
1267
1624
|
{
|
|
1268
1625
|
articleSlug,
|
|
@@ -1274,7 +1631,7 @@ function CommentItem({
|
|
|
1274
1631
|
onCancel: () => setShowReplyForm(false)
|
|
1275
1632
|
}
|
|
1276
1633
|
) }),
|
|
1277
|
-
replies.length > 0 && /* @__PURE__ */
|
|
1634
|
+
replies.length > 0 && /* @__PURE__ */ jsx22("div", { className: "mt-2 space-y-2", children: replies.map((reply) => /* @__PURE__ */ jsx22(
|
|
1278
1635
|
CommentItem,
|
|
1279
1636
|
{
|
|
1280
1637
|
comment: __spreadProps(__spreadValues({}, reply), { replies: [] }),
|
|
@@ -1289,7 +1646,7 @@ function CommentItem({
|
|
|
1289
1646
|
}
|
|
1290
1647
|
|
|
1291
1648
|
// src/CommentThread.tsx
|
|
1292
|
-
import { jsx as
|
|
1649
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1293
1650
|
function CommentThread({
|
|
1294
1651
|
comments,
|
|
1295
1652
|
articleSlug,
|
|
@@ -1297,9 +1654,9 @@ function CommentThread({
|
|
|
1297
1654
|
onRefresh
|
|
1298
1655
|
}) {
|
|
1299
1656
|
if (comments.length === 0) {
|
|
1300
|
-
return /* @__PURE__ */
|
|
1657
|
+
return /* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground text-center py-6", children: "No comments yet. Be the first to share your thoughts." });
|
|
1301
1658
|
}
|
|
1302
|
-
return /* @__PURE__ */
|
|
1659
|
+
return /* @__PURE__ */ jsx23("div", { className: "space-y-4", children: comments.map((comment) => /* @__PURE__ */ jsx23(
|
|
1303
1660
|
CommentItem,
|
|
1304
1661
|
{
|
|
1305
1662
|
comment,
|
|
@@ -1312,7 +1669,7 @@ function CommentThread({
|
|
|
1312
1669
|
}
|
|
1313
1670
|
|
|
1314
1671
|
// src/CommentsSection.tsx
|
|
1315
|
-
import { jsx as
|
|
1672
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1316
1673
|
function CommentsSection({ articleSlug, config }) {
|
|
1317
1674
|
var _a, _b, _c, _d, _e, _f;
|
|
1318
1675
|
const { data: session, status } = useSession();
|
|
@@ -1344,10 +1701,10 @@ function CommentsSection({ articleSlug, config }) {
|
|
|
1344
1701
|
if (!enabled) return null;
|
|
1345
1702
|
const count = comments.length;
|
|
1346
1703
|
const label = count === 1 ? "1 comment" : `${count} comments`;
|
|
1347
|
-
return /* @__PURE__ */
|
|
1348
|
-
/* @__PURE__ */
|
|
1349
|
-
status === "authenticated" ? /* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1704
|
+
return /* @__PURE__ */ jsxs22("section", { "aria-label": "Comments", className: "mt-12 pt-8 border-t border-border space-y-6", children: [
|
|
1705
|
+
/* @__PURE__ */ jsx24("h2", { className: "text-xl font-semibold text-foreground", children: loading ? "Comments" : label }),
|
|
1706
|
+
status === "authenticated" ? /* @__PURE__ */ jsx24(CommentForm, { articleSlug, onSuccess: fetchComments }) : /* @__PURE__ */ jsxs22("p", { className: "text-sm text-muted-foreground", children: [
|
|
1707
|
+
/* @__PURE__ */ jsx24(
|
|
1351
1708
|
"button",
|
|
1352
1709
|
{
|
|
1353
1710
|
onClick: () => signIn(),
|
|
@@ -1358,8 +1715,8 @@ function CommentsSection({ articleSlug, config }) {
|
|
|
1358
1715
|
" ",
|
|
1359
1716
|
"to join the discussion."
|
|
1360
1717
|
] }),
|
|
1361
|
-
fetchError && /* @__PURE__ */
|
|
1362
|
-
loading ? /* @__PURE__ */
|
|
1718
|
+
fetchError && /* @__PURE__ */ jsx24("p", { className: "text-sm text-destructive", children: fetchError }),
|
|
1719
|
+
loading ? /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "Loading comments\u2026" }) : /* @__PURE__ */ jsx24(
|
|
1363
1720
|
CommentThread,
|
|
1364
1721
|
{
|
|
1365
1722
|
comments,
|
|
@@ -1383,6 +1740,11 @@ export {
|
|
|
1383
1740
|
ArticleTOC,
|
|
1384
1741
|
ArticlesHero,
|
|
1385
1742
|
ArticlesPage,
|
|
1743
|
+
AuthorArticlesPage,
|
|
1744
|
+
AuthorCard,
|
|
1745
|
+
AuthorDetailHero,
|
|
1746
|
+
AuthorSocialLinks,
|
|
1747
|
+
Breadcrumb,
|
|
1386
1748
|
BreadcrumbSchema,
|
|
1387
1749
|
CategoryArticlesPage,
|
|
1388
1750
|
CollectionPageSchema,
|
|
@@ -1398,6 +1760,8 @@ export {
|
|
|
1398
1760
|
LatestArticles,
|
|
1399
1761
|
LatestArticlesSection,
|
|
1400
1762
|
ScrollToTop,
|
|
1763
|
+
breadcrumbsAreEnabled,
|
|
1764
|
+
getBreadcrumbsConfig,
|
|
1401
1765
|
useArticles
|
|
1402
1766
|
};
|
|
1403
1767
|
//# sourceMappingURL=index.js.map
|