fix: pre-launch UI hardening + KOL reduce-action type, proxy IP relay, settings redesign
Frontend half of the pre-launch audit campaign: - types/index.ts + kol/KolPageClient.tsx: add missing 'reduce' KolAction (backend emits it; frontend lacked the type + color/label maps → undefined styling). Adds ACTION_COLOR/actionLabel/postActionLabel entries. - proxy/[...path]/route.ts: relay real client IP (x-forwarded-for / x-real-ip) so the backend rate limiter buckets per-user instead of per-Next-server (BUG-02). - Settings/BotConfigPanel redesign, paper-mode clarity, copy cleanup. - Assorted page/display fixes, loading states, Pagination component. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,9 @@ import type { TrumpPost } from '@/types'
|
||||
import { getPosts } from '@/lib/api'
|
||||
import PostRow from '@/components/dashboard/PostCards'
|
||||
import PageHint from '@/components/ui/PageHint'
|
||||
import Pagination from '@/components/ui/Pagination'
|
||||
|
||||
const ARCHIVE_PAGE_SIZE = 30
|
||||
|
||||
const LIVE_SOURCES = new Set([
|
||||
'truth',
|
||||
@@ -25,6 +28,7 @@ export default function ArchivePage() {
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [loadErr, setLoadErr] = useState('')
|
||||
const [src, setSrc] = useState<string>('all')
|
||||
const [archivePage, setArchivePage] = useState(1)
|
||||
|
||||
useEffect(() => {
|
||||
getPosts(500, 1)
|
||||
@@ -49,6 +53,9 @@ export default function ArchivePage() {
|
||||
() => src === 'all' ? archivePosts : archivePosts.filter(p => p.source === src),
|
||||
[archivePosts, src],
|
||||
)
|
||||
const archiveTotalPages = Math.max(1, Math.ceil(filtered.length / ARCHIVE_PAGE_SIZE))
|
||||
const archiveSafePage = Math.min(archivePage, archiveTotalPages)
|
||||
const archivePageItems = filtered.slice((archiveSafePage - 1) * ARCHIVE_PAGE_SIZE, archiveSafePage * ARCHIVE_PAGE_SIZE)
|
||||
|
||||
return (
|
||||
<div className="page">
|
||||
@@ -67,7 +74,7 @@ export default function ArchivePage() {
|
||||
{[['all', archivePosts.length] as [string, number], ...sources].map(([s, n]) => (
|
||||
<button
|
||||
key={s}
|
||||
onClick={() => setSrc(s)}
|
||||
onClick={() => { setSrc(s); setArchivePage(1) }}
|
||||
style={{
|
||||
padding: '4px 10px', borderRadius: 6, border: '1px solid var(--line)',
|
||||
background: src === s ? 'var(--ink)' : 'transparent',
|
||||
@@ -95,10 +102,19 @@ export default function ArchivePage() {
|
||||
{isZh ? '没有可显示的历史信号。' : 'No archived signals.'}
|
||||
</div>
|
||||
)}
|
||||
{!loading && filtered.length > 0 && (
|
||||
<div className="post-stream">
|
||||
{filtered.map(p => <PostRow key={p.id} post={p} />)}
|
||||
</div>
|
||||
{!loading && archivePageItems.length > 0 && (
|
||||
<>
|
||||
<div className="post-stream">
|
||||
{archivePageItems.map(p => <PostRow key={p.id} post={p} />)}
|
||||
</div>
|
||||
<Pagination
|
||||
page={archiveSafePage}
|
||||
total={archiveTotalPages}
|
||||
count={filtered.length}
|
||||
pageSize={ARCHIVE_PAGE_SIZE}
|
||||
onChange={setArchivePage}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user