fix: pre-landing and adversarial review fixes
- landing.css: hardcode --lp-btn to #60a5fa (lesson 104 — no var(--color-*) in landing.css) - ScriptBuilderInput: suggestion chips now correctly disabled during generation - ChatSidebar: wrapper onClick no longer fires onSelect while in confirming state - SessionHistoryPage: fix loadMoreAiSessions race condition with generation counter; flow session tab auto-activates when URL params target flow session filters Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -189,7 +189,7 @@ function ChatItem({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onClick={onSelect}
|
onClick={confirming ? e => e.stopPropagation() : onSelect}
|
||||||
className={cn(
|
className={cn(
|
||||||
'group flex items-center gap-2 px-3 py-2.5 mx-1.5 rounded-lg cursor-pointer transition-colors',
|
'group flex items-center gap-2 px-3 py-2.5 mx-1.5 rounded-lg cursor-pointer transition-colors',
|
||||||
confirming
|
confirming
|
||||||
|
|||||||
@@ -92,8 +92,9 @@ export function ScriptBuilderInput({
|
|||||||
<button
|
<button
|
||||||
key={label}
|
key={label}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => onSend(label)}
|
disabled={disabled}
|
||||||
className="group flex items-center gap-1.5 rounded-md border border-border bg-card px-3 py-1.5 text-xs text-muted-foreground transition-all hover:border-[var(--color-border-hover)] hover:bg-[var(--color-bg-elevated)] hover:text-foreground active:scale-[0.97]"
|
onClick={() => { if (!disabled) onSend(label) }}
|
||||||
|
className="group flex items-center gap-1.5 rounded-md border border-border bg-card px-3 py-1.5 text-xs text-muted-foreground transition-all hover:border-[var(--color-border-hover)] hover:bg-[var(--color-bg-elevated)] hover:text-foreground active:scale-[0.97] disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none"
|
||||||
>
|
>
|
||||||
<Icon size={11} className="text-muted shrink-0 group-hover:text-[#f97316] transition-colors" />
|
<Icon size={11} className="text-muted shrink-0 group-hover:text-[#f97316] transition-colors" />
|
||||||
{label}
|
{label}
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ type TabId = typeof TABS[number]['id']
|
|||||||
export default function SessionHistoryPage() {
|
export default function SessionHistoryPage() {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [searchParams, setSearchParams] = useSearchParams()
|
const [searchParams, setSearchParams] = useSearchParams()
|
||||||
const [activeTab, setActiveTab] = useState<TabId>('ai')
|
const [activeTab, setActiveTab] = useState<TabId>(() => {
|
||||||
|
// If URL params target flow session filters, start on flows tab
|
||||||
|
const hasFlowParams = searchParams.get('ticket') || searchParams.get('client') || searchParams.get('tree')
|
||||||
|
return hasFlowParams ? 'flows' : 'ai'
|
||||||
|
})
|
||||||
|
|
||||||
// ── AI Session state ──
|
// ── AI Session state ──
|
||||||
const [aiSessions, setAiSessions] = useState<AISessionSummary[]>([])
|
const [aiSessions, setAiSessions] = useState<AISessionSummary[]>([])
|
||||||
@@ -38,6 +42,7 @@ export default function SessionHistoryPage() {
|
|||||||
const [aiHasMore, setAiHasMore] = useState(false)
|
const [aiHasMore, setAiHasMore] = useState(false)
|
||||||
const [aiSearchInput, setAiSearchInput] = useState('')
|
const [aiSearchInput, setAiSearchInput] = useState('')
|
||||||
const aiSearchTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
|
const aiSearchTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
|
||||||
|
const aiFilterGenRef = useRef(0)
|
||||||
const [aiFilters, setAiFilters] = useState({
|
const [aiFilters, setAiFilters] = useState({
|
||||||
q: '',
|
q: '',
|
||||||
session_type: '',
|
session_type: '',
|
||||||
@@ -85,6 +90,9 @@ export default function SessionHistoryPage() {
|
|||||||
// ── AI Sessions: fetch ──
|
// ── AI Sessions: fetch ──
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false
|
let cancelled = false
|
||||||
|
const gen = ++aiFilterGenRef.current
|
||||||
|
setAiSessions([])
|
||||||
|
setAiHasMore(false)
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
setAiLoading(true)
|
setAiLoading(true)
|
||||||
try {
|
try {
|
||||||
@@ -97,7 +105,7 @@ export default function SessionHistoryPage() {
|
|||||||
date_from: aiFilters.date_from || undefined,
|
date_from: aiFilters.date_from || undefined,
|
||||||
date_to: aiFilters.date_to ? `${aiFilters.date_to}T23:59:59.999Z` : undefined,
|
date_to: aiFilters.date_to ? `${aiFilters.date_to}T23:59:59.999Z` : undefined,
|
||||||
})
|
})
|
||||||
if (!cancelled) {
|
if (!cancelled && gen === aiFilterGenRef.current) {
|
||||||
setAiSessions(data)
|
setAiSessions(data)
|
||||||
setAiHasMore(data.length >= PAGE_SIZE)
|
setAiHasMore(data.length >= PAGE_SIZE)
|
||||||
}
|
}
|
||||||
@@ -112,6 +120,7 @@ export default function SessionHistoryPage() {
|
|||||||
}, [aiFilters])
|
}, [aiFilters])
|
||||||
|
|
||||||
const loadMoreAiSessions = async () => {
|
const loadMoreAiSessions = async () => {
|
||||||
|
const gen = aiFilterGenRef.current
|
||||||
setAiLoadingMore(true)
|
setAiLoadingMore(true)
|
||||||
try {
|
try {
|
||||||
const data = await aiSessionsApi.listSessions({
|
const data = await aiSessionsApi.listSessions({
|
||||||
@@ -124,8 +133,10 @@ export default function SessionHistoryPage() {
|
|||||||
date_from: aiFilters.date_from || undefined,
|
date_from: aiFilters.date_from || undefined,
|
||||||
date_to: aiFilters.date_to ? `${aiFilters.date_to}T23:59:59.999Z` : undefined,
|
date_to: aiFilters.date_to ? `${aiFilters.date_to}T23:59:59.999Z` : undefined,
|
||||||
})
|
})
|
||||||
setAiSessions(prev => [...prev, ...data])
|
if (gen === aiFilterGenRef.current) {
|
||||||
setAiHasMore(data.length >= PAGE_SIZE)
|
setAiSessions(prev => [...prev, ...data])
|
||||||
|
setAiHasMore(data.length >= PAGE_SIZE)
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
toast.error('Failed to load more sessions')
|
toast.error('Failed to load more sessions')
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
--lp-accent: #60a5fa;
|
--lp-accent: #60a5fa;
|
||||||
--lp-accent-soft: rgba(96, 165, 250, 0.10);
|
--lp-accent-soft: rgba(96, 165, 250, 0.10);
|
||||||
--lp-accent-text: #93bbfc;
|
--lp-accent-text: #93bbfc;
|
||||||
--lp-btn: var(--color-accent, #f97316);
|
--lp-btn: #60a5fa;
|
||||||
--lp-success: #34d399;
|
--lp-success: #34d399;
|
||||||
--lp-danger: #f87171;
|
--lp-danger: #f87171;
|
||||||
--lp-warning: #fbbf24;
|
--lp-warning: #fbbf24;
|
||||||
|
|||||||
Reference in New Issue
Block a user