Q&A: pinned questions are featured on the home page, home cards link to the full answer, newest answer first; v2.22.1
Publish Container / build (push) Successful in 16m39s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-12 14:30:04 -04:00
1 parent 960ee41375
commit 4a7c3cc967
6 files changed
+21 -7

No files matched your search

+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "siteforge",
"version": "2.22.0",
"version": "2.22.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "siteforge",
"version": "2.22.0",
"version": "2.22.1",
"dependencies": {
"@aws-sdk/client-s3": "^3.1135.0",
"@dnd-kit/core": "^6.3.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "siteforge",
"private": true,
"version": "2.22.0",
"version": "2.22.1",
"type": "module",
"scripts": {
"dev": "vite",
+4 -2
View File
@@ -76,10 +76,12 @@ export function register(app) {
const publicQuestions = sourceQuestions
.filter(q => q.isApproved === true && q.answer && q.answer.trim().length > 0)
.sort((a, b) => {
// Pinned questions always float to top
// Pinned first (they are also the ones featured on the home page), then newest answer first
if (a.pinned && !b.pinned) return -1
if (!a.pinned && b.pinned) return 1
return 0
const at = new Date(a.answeredAt ?? a.submittedAt ?? 0).getTime() || 0
const bt = new Date(b.answeredAt ?? b.submittedAt ?? 0).getTime() || 0
return bt - at
})
res.json({ questions: publicQuestions.map(toPublicQuestion) })
})
+11
View File
@@ -1349,6 +1349,17 @@
margin: 0;
}
.qa-callout-more {
margin-top: auto;
font-size: 0.85rem;
color: var(--brand-gold);
text-decoration: none;
}
.qa-callout-more:hover {
text-decoration: underline;
}
/* ── Home Jump Section ── */
/* ── Truth For Life Widget ── */
.section-tfl {
+1
View File
@@ -1260,6 +1260,7 @@ function HomepageQACallout() {
<p className="qa-callout-question">"{q.question}"</p>
<p className="qa-callout-answer">{q.answer.length > 220 ? q.answer.slice(0, 220).trimEnd() + '…' : q.answer}</p>
{q.firstName && <p className="qa-callout-from">— {q.firstName}</p>}
<Link to={`/questions#qa-${q.id}`} className="qa-callout-more">Read the full answer →</Link>
</div>
))}
</div>
+2 -2
View File
@@ -195,7 +195,7 @@ export function QuestionsAdmin({ questions, onChange }: Props) {
<section className="admin-panel-section" aria-label="Questions and answers">
<div className="admin-panel-head">
<h2>Bible Questions &amp; Answers</h2>
<p>Work through questions from the top: write an answer, set a topic, and publish. Published answers appear on the public Q&amp;A page right away.</p>
<p>Work through questions from the top: write an answer, set a topic, and publish. Published answers appear on the public Q&amp;A page right away. Pinned questions show first there and are featured on the home page.</p>
</div>
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 12, alignItems: 'center' }}>
@@ -350,7 +350,7 @@ export function QuestionsAdmin({ questions, onChange }: Props) {
<button type="button" className="btn-admin-ghost" onClick={saveFields} disabled={busy || !dirty}>Save draft</button>
</>
)}
<button type="button" className="btn-admin-ghost" onClick={togglePin} disabled={busy}>{selected.pinned ? 'Unpin' : 'Pin to top'}</button>
<button type="button" className="btn-admin-ghost" onClick={togglePin} disabled={busy} title="Pinned questions show first on the Q&A page and are featured on the home page">{selected.pinned ? 'Unpin' : 'Pin & feature'}</button>
<button type="button" className="btn-admin-remove" onClick={() => remove([selected.id])} disabled={busy}>Delete</button>
{dirty && <span className="admin-stats-note">Unsaved changes</span>}
</div>