From 2d7b5abf684b1ea4c4d507b052db53592c20bd59 Mon Sep 17 00:00:00 2001 From: NeilJo-GY <43027886+NeilJo-GY@users.noreply.github.com> Date: Fri, 2 Oct 2026 13:02:37 +0800 Subject: [PATCH] fix: P2 polish sweep across chat shell, panels, and site pages Chat shell: click-only account menu, directional bubbles with capped width, shared composer chip row, unified avatar gradient tokens, SVG icons instead of emoji, listbox/combobox ARIA for slash and mention menus, collab top-up CTA, 100dvh + safe-area composer. Panels: FieldHint i18n label + larger hit area, i18n loading labels, wallet flash auto-dismiss, inline amount validation, reject confirm with row-wide disable, dialog aria-labels, MailboxThumbs alt/failure state, picker checkbox + i18n mode tabs, hardcoded colors moved to tokens, shared inputStyle. Site: join page missing-invite guidance, CN transfer layout aligned with global claim, Auth0 callback error page styling, CSS var tokens for success/danger/info, disabled cursor rule, plan sheet contrast. Co-authored-by: Cursor --- packages/agent-chat/src/MailboxThumbs.tsx | 38 ++- .../src/ranch-shell/AccountPanels.tsx | 75 ++--- .../src/ranch-shell/AgentOwnerSettings.tsx | 50 +-- .../src/ranch-shell/AgentOwnerWallet.tsx | 52 ++- .../src/ranch-shell/MyAgentsPanel.tsx | 1 + .../src/ranch-shell/NewChatPicker.tsx | 31 +- .../src/ranch-shell/NewComposeMenu.tsx | 120 +++++-- .../src/ranch-shell/RanchChatShell.tsx | 302 +++++++++++------- packages/agent-chat/src/ranch-shell/i18n.ts | 37 ++- packages/agent-chat/src/ranch-shell/styles.ts | 9 +- src/app/auth/callback/page.tsx | 33 +- src/app/auth/wechat/callback/page.tsx | 2 +- src/app/claim/[id]/page.tsx | 4 +- src/app/globals.css | 7 + src/app/join/page.tsx | 27 +- src/app/subscribe/page.tsx | 6 +- src/app/transfer/accept/page.tsx | 4 +- src/app/wallet/page.tsx | 6 +- src/components/CnClaim.tsx | 4 +- src/components/CnJoin.tsx | 4 +- src/components/CnSubscribeCheckout.tsx | 4 +- src/components/CnTransferAccept.tsx | 15 +- src/components/CnWalletCheckout.tsx | 4 +- src/components/InterfazeEmbedHost.tsx | 2 +- src/components/LandingGate.tsx | 2 +- src/components/PlanCatalog.tsx | 2 +- 26 files changed, 562 insertions(+), 279 deletions(-) diff --git a/packages/agent-chat/src/MailboxThumbs.tsx b/packages/agent-chat/src/MailboxThumbs.tsx index c2b02f1..b9de42e 100644 --- a/packages/agent-chat/src/MailboxThumbs.tsx +++ b/packages/agent-chat/src/MailboxThumbs.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from "react"; import { mailboxIdsFromAttachments, parseMessageAttachments, isReadableAttachmentName } from "./mailbox"; +import { colors } from "./ranch-shell/styles"; function joinUrl(base: string, path: string): string { const b = base.replace(/\/+$/, ""); @@ -51,7 +52,7 @@ function ListedTag({ n }: { n: number }) { borderRadius: 999, background: "rgba(0,0,0,0.72)", color: "#fff", - fontSize: 11, + fontSize: 12, lineHeight: 1.4, pointerEvents: "none", }} @@ -66,18 +67,22 @@ export function MailboxThumbs({ attachments, gatewayBaseUrl, getAccessToken, + loadFailedLabel = "Attachment failed to load", }: { chatId: string; attachments?: string[] | string | null; gatewayBaseUrl: string; getAccessToken: () => Promise; + loadFailedLabel?: string; }) { const ids = mailboxIdsFromAttachments(parseMessageAttachments(attachments ?? [])); const [files, setFiles] = useState([]); + const [failedIds, setFailedIds] = useState([]); useEffect(() => { if (ids.length === 0 || !chatId) { setFiles([]); + setFailedIds([]); return; } let cancelled = false; @@ -86,6 +91,7 @@ export function MailboxThumbs({ const token = await getAccessToken(); if (!token || cancelled) return; const next: FileBlob[] = []; + const failed: string[] = []; for (const id of ids) { try { const res = await fetch( @@ -95,7 +101,10 @@ export function MailboxThumbs({ ), { headers: { Authorization: `Bearer ${token}` } }, ); - if (!res.ok) continue; + if (!res.ok) { + failed.push(id); + continue; + } const blob = await res.blob(); const url = URL.createObjectURL(blob); created.push(url); @@ -114,10 +123,13 @@ export function MailboxThumbs({ ), }); } catch { - /* skip broken blob */ + failed.push(id); } } - if (!cancelled) setFiles(next); + if (!cancelled) { + setFiles(next); + setFailedIds(failed); + } })(); return () => { cancelled = true; @@ -132,7 +144,7 @@ export function MailboxThumbs({ f.contentType.startsWith("image/"); return playable || isReadableAttachmentName(f.name, f.mailboxId); }); - if (visible.length === 0) return null; + if (visible.length === 0 && failedIds.length === 0) return null; return (
); @@ -194,6 +206,20 @@ export function MailboxThumbs({
); })} + {failedIds.map((id) => ( +
+ {loadFailedLabel} +
+ ))} ); } diff --git a/packages/agent-chat/src/ranch-shell/AccountPanels.tsx b/packages/agent-chat/src/ranch-shell/AccountPanels.tsx index 2eb13b0..f06da7a 100644 --- a/packages/agent-chat/src/ranch-shell/AccountPanels.tsx +++ b/packages/agent-chat/src/ranch-shell/AccountPanels.tsx @@ -17,7 +17,7 @@ import type { import type { RanchChatAccount } from "../types"; import { AgentOwnerWallet } from "./AgentOwnerWallet"; import type { RanchLocale, RanchMessages } from "./i18n"; -import { btnGhost, btnIcon, btnPrimary, colors } from "./styles"; +import { btnGhost, btnIcon, btnPrimary, colors, inputStyle } from "./styles"; import { useModalA11y } from "./useModalA11y"; import { buildWalletCheckoutUrl, @@ -86,9 +86,9 @@ function Badge({ }) { const palette: CSSProperties = tone === "accent" - ? { background: colors.accentSoft, color: "#7aa2f7" } + ? { background: colors.accentSoft, color: colors.accentBright } : tone === "ok" - ? { background: "rgba(16,185,129,0.14)", color: "#34d399" } + ? { background: "rgba(16,185,129,0.14)", color: colors.success } : { background: "rgba(255,255,255,0.07)", color: colors.muted }; return ( @@ -930,15 +930,7 @@ export function AccountPlanUsagePanel({ step={1} value={limitInput} onChange={(e) => setLimitInput(e.target.value)} - style={{ - width: 72, - border: `1px solid ${colors.border}`, - background: "#121820", - color: colors.text, - borderRadius: 8, - padding: "6px 8px", - fontSize: 13, - }} + style={{ ...inputStyle, width: 72, padding: "6px 8px" }} /> ) : null}
- × + ✕
@@ -1407,7 +1399,7 @@ function CheckoutEmbedDialog({ src={url} allow="payment" referrerPolicy="strict-origin-when-cross-origin" - style={{ flex: 1, width: "100%", border: 0, background: "#0a0a0a" }} + style={{ flex: 1, width: "100%", border: 0, background: colors.embedBg }} /> @@ -1482,15 +1474,7 @@ export function ChatCollabBudgetSection({ min={0} value={capDraft} onChange={(e) => setCapDraft(e.target.value)} - style={{ - flex: 1, - padding: "9px 12px", - borderRadius: 10, - border: `1px solid ${colors.border}`, - background: colors.bg, - color: colors.text, - fontSize: 14, - }} + style={{ ...inputStyle, flex: 1, padding: "9px 12px", fontSize: 14 }} /> {providerOptions.length === 0 ? ( @@ -2463,7 +2468,7 @@ export function AgentOwnerSettings({ ? t.myAgentsPricingSourceOpenRouter : t.myAgentsPricingSourceTokenHub} - +
) : null} @@ -2586,7 +2591,7 @@ export function AgentOwnerSettings({ in: String(usdToCredits(inputParsed)), out: String(usdToCredits(outputParsed)), })} - + ) : null} @@ -2605,7 +2610,7 @@ export function AgentOwnerSettings({

{t.myAgentsSectionPieceSku} - +

{t.myAgentsPieceSkuOff} @@ -2641,7 +2646,7 @@ export function AgentOwnerSettings({ disabled={!canSavePieceSku} onClick={() => void runSavePieceSku()} > - {savingPieceSku ? "…" : t.myAgentsSavePieceSku} + {savingPieceSku ? t.loading : t.myAgentsSavePieceSku}

@@ -2669,7 +2674,7 @@ export function AgentOwnerSettings({ >
{t.myAgentsDeliveryOptionPull}
- +
- +
{deliveryDraft === "direct" ? (