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:
k
2026-05-29 11:57:43 +08:00
parent b76de36af0
commit d50c05b120
32 changed files with 1003 additions and 224 deletions
+17 -1
View File
@@ -27,9 +27,18 @@ export interface SignConfirmOptions {
danger?: boolean
}
// Track the currently-mounted sheet so a second confirmSign() call can resolve
// the first one with `false` instead of leaving its promise dangling forever.
let _activeCancel: (() => void) | null = null
/** Renders a confirmation sheet and resolves true (confirm) or false (cancel). */
export function confirmSign(opts: SignConfirmOptions): Promise<boolean> {
return new Promise((resolve) => {
// If another sheet is already mounted, cancel it first so its awaiting
// caller resolves with `false` rather than hanging indefinitely.
if (_activeCancel) {
try { _activeCancel() } catch { /* ignore */ }
}
const existing = document.getElementById('sign-confirm-sheet-root')
if (existing?.parentNode) {
existing.parentNode.removeChild(existing)
@@ -43,6 +52,9 @@ export function confirmSign(opts: SignConfirmOptions): Promise<boolean> {
function cleanup(result: boolean) {
if (settled) return
settled = true
// Clear the active-cancel slot only if it still points to *this* sheet —
// a later confirmSign() may have already replaced it.
if (_activeCancel === cancelSelf) _activeCancel = null
root.unmount()
if (container.parentNode) {
container.parentNode.removeChild(container)
@@ -50,7 +62,11 @@ export function confirmSign(opts: SignConfirmOptions): Promise<boolean> {
resolve(result)
}
root.render(<Sheet {...opts} onConfirm={() => cleanup(true)} onCancel={() => cleanup(false)} />)
// Stable reference used both as the active-cancel handle and inside cleanup.
const cancelSelf = () => cleanup(false)
_activeCancel = cancelSelf
root.render(<Sheet {...opts} onConfirm={() => cleanup(true)} onCancel={cancelSelf} />)
})
}