Wire admin studio SSR and search infrastructure
This commit is contained in:
@@ -3,8 +3,9 @@ import Breadcrumbs from '../../components/forum/Breadcrumbs'
|
||||
import ThreadRow from '../../components/forum/ThreadRow'
|
||||
import Pagination from '../../components/forum/Pagination'
|
||||
import Button from '../../components/ui/Button'
|
||||
import SeoHead from '../../components/seo/SeoHead'
|
||||
|
||||
export default function ForumCategory({ category, parentCategory = null, threads = [], pagination = {}, isAuthenticated = false }) {
|
||||
export default function ForumCategory({ category, parentCategory = null, threads = [], pagination = {}, isAuthenticated = false, seo = {} }) {
|
||||
const name = category?.name ?? 'Category'
|
||||
const slug = category?.slug
|
||||
|
||||
@@ -16,7 +17,9 @@ export default function ForumCategory({ category, parentCategory = null, threads
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-5xl mx-auto">
|
||||
<>
|
||||
<SeoHead seo={seo} />
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-5xl mx-auto">
|
||||
{/* Breadcrumbs */}
|
||||
<Breadcrumbs items={breadcrumbs} />
|
||||
|
||||
@@ -79,5 +82,6 @@ export default function ForumCategory({ category, parentCategory = null, threads
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@ import Button from '../../components/ui/Button'
|
||||
import RichTextEditor from '../../components/forum/RichTextEditor'
|
||||
import TurnstileField from '../../components/security/TurnstileField'
|
||||
import { populateBotFingerprint } from '../../lib/security/botFingerprint'
|
||||
import SeoHead from '../../components/seo/SeoHead'
|
||||
|
||||
export default function ForumEditPost({ post, thread, csrfToken, errors = {}, captcha = {} }) {
|
||||
export default function ForumEditPost({ post, thread, csrfToken, errors = {}, captcha = {}, seo = {} }) {
|
||||
const [content, setContent] = useState(post?.content ?? '')
|
||||
const [captchaToken, setCaptchaToken] = useState('')
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
@@ -19,16 +20,22 @@ export default function ForumEditPost({ post, thread, csrfToken, errors = {}, ca
|
||||
|
||||
const handleSubmit = useCallback((e) => {
|
||||
if (submitting) return
|
||||
setSubmitting(true)
|
||||
// Let the form submit normally for PRG
|
||||
populateBotFingerprint(e.currentTarget).finally(() => {
|
||||
e.currentTarget.submit()
|
||||
})
|
||||
|
||||
e.preventDefault()
|
||||
setSubmitting(true)
|
||||
|
||||
const form = e.currentTarget
|
||||
|
||||
// Let the form submit normally for PRG.
|
||||
populateBotFingerprint(form).finally(() => {
|
||||
form?.submit()
|
||||
})
|
||||
}, [submitting])
|
||||
|
||||
return (
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-3xl mx-auto">
|
||||
<>
|
||||
<SeoHead seo={seo} />
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-3xl mx-auto">
|
||||
<Breadcrumbs items={breadcrumbs} />
|
||||
|
||||
{/* Header */}
|
||||
@@ -101,5 +108,6 @@ export default function ForumEditPost({ post, thread, csrfToken, errors = {}, ca
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from 'react'
|
||||
import CategoryCard from '../../components/forum/CategoryCard'
|
||||
import SeoHead from '../../components/seo/SeoHead'
|
||||
|
||||
export default function ForumIndex({ categories = [], trendingTopics = [], latestTopics = [] }) {
|
||||
export default function ForumIndex({ categories = [], trendingTopics = [], latestTopics = [], seo = {} }) {
|
||||
const totalThreads = categories.reduce((sum, cat) => sum + (Number(cat?.thread_count) || 0), 0)
|
||||
const totalPosts = categories.reduce((sum, cat) => sum + (Number(cat?.post_count) || 0), 0)
|
||||
const sortedByActivity = [...categories].sort((a, b) => {
|
||||
@@ -12,7 +13,9 @@ export default function ForumIndex({ categories = [], trendingTopics = [], lates
|
||||
const latestActive = sortedByActivity[0] ?? null
|
||||
|
||||
return (
|
||||
<div className="pb-20">
|
||||
<>
|
||||
<SeoHead seo={seo} />
|
||||
<div className="pb-20">
|
||||
<section className="relative overflow-hidden border-b border-white/10 bg-[radial-gradient(circle_at_15%_20%,rgba(34,211,238,0.24),transparent_40%),radial-gradient(circle_at_80%_0%,rgba(56,189,248,0.16),transparent_42%),linear-gradient(180deg,rgba(10,14,26,0.96),rgba(8,12,22,0.92))]">
|
||||
<div className="pointer-events-none absolute inset-0 opacity-40 [background-image:linear-gradient(rgba(255,255,255,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.06)_1px,transparent_1px)] [background-size:40px_40px]" />
|
||||
|
||||
@@ -93,6 +96,7 @@ export default function ForumIndex({ categories = [], trendingTopics = [], lates
|
||||
<Panel title="Latest Topics" items={latestTopics} emptyLabel="Latest topics will appear here." />
|
||||
</section>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ import TextInput from '../../components/ui/TextInput'
|
||||
import RichTextEditor from '../../components/forum/RichTextEditor'
|
||||
import TurnstileField from '../../components/security/TurnstileField'
|
||||
import { populateBotFingerprint } from '../../lib/security/botFingerprint'
|
||||
import SeoHead from '../../components/seo/SeoHead'
|
||||
|
||||
export default function ForumNewThread({ category, csrfToken, errors = {}, oldValues = {}, captcha = {} }) {
|
||||
export default function ForumNewThread({ category, csrfToken, errors = {}, oldValues = {}, captcha = {}, seo = {} }) {
|
||||
const [title, setTitle] = useState(oldValues.title ?? '')
|
||||
const [content, setContent] = useState(oldValues.content ?? '')
|
||||
const [captchaToken, setCaptchaToken] = useState('')
|
||||
@@ -33,7 +34,9 @@ export default function ForumNewThread({ category, csrfToken, errors = {}, oldVa
|
||||
}, [submitting])
|
||||
|
||||
return (
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-3xl mx-auto">
|
||||
<>
|
||||
<SeoHead seo={seo} />
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-3xl mx-auto">
|
||||
<Breadcrumbs items={breadcrumbs} />
|
||||
|
||||
{/* Header */}
|
||||
@@ -115,5 +118,6 @@ export default function ForumNewThread({ category, csrfToken, errors = {}, oldVa
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from 'react'
|
||||
import Breadcrumbs from '../../components/forum/Breadcrumbs'
|
||||
import SeoHead from '../../components/seo/SeoHead'
|
||||
|
||||
export default function ForumSection({ category, boards = [] }) {
|
||||
export default function ForumSection({ category, boards = [], seo = {} }) {
|
||||
const name = category?.name ?? 'Forum Section'
|
||||
const description = category?.description
|
||||
const preview = category?.preview_image ?? '/images/forum/default.jpg'
|
||||
@@ -13,7 +14,9 @@ export default function ForumSection({ category, boards = [] }) {
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-6xl px-4 pb-20 pt-10 sm:px-6 lg:px-8">
|
||||
<>
|
||||
<SeoHead seo={seo} />
|
||||
<div className="mx-auto max-w-6xl px-4 pb-20 pt-10 sm:px-6 lg:px-8">
|
||||
<Breadcrumbs items={breadcrumbs} />
|
||||
|
||||
<section className="mt-5 overflow-hidden rounded-3xl border border-white/10 bg-nova-800/55 shadow-xl backdrop-blur">
|
||||
@@ -64,5 +67,6 @@ export default function ForumSection({ category, boards = [] }) {
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import Breadcrumbs from '../../components/forum/Breadcrumbs'
|
||||
import PostCard from '../../components/forum/PostCard'
|
||||
import ReplyForm from '../../components/forum/ReplyForm'
|
||||
import Pagination from '../../components/forum/Pagination'
|
||||
import SeoHead from '../../components/seo/SeoHead'
|
||||
|
||||
export default function ForumThread({
|
||||
thread,
|
||||
@@ -21,6 +22,7 @@ export default function ForumThread({
|
||||
csrfToken = '',
|
||||
status = null,
|
||||
captcha = {},
|
||||
seo = {},
|
||||
}) {
|
||||
const [currentSort, setCurrentSort] = useState(sort)
|
||||
|
||||
@@ -41,7 +43,9 @@ export default function ForumThread({
|
||||
}, [currentSort])
|
||||
|
||||
return (
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-5xl mx-auto space-y-5">
|
||||
<>
|
||||
<SeoHead seo={seo} />
|
||||
<div className="px-4 pt-10 pb-20 sm:px-6 lg:px-8 max-w-5xl mx-auto space-y-5">
|
||||
<Breadcrumbs items={breadcrumbs} />
|
||||
|
||||
{/* Status flash */}
|
||||
@@ -176,6 +180,7 @@ export default function ForumThread({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user