fix(ui): thème, textes et lisibilité restants de la revue
Les boutons suivent la couleur d’apparence, les libellés trop petits ou trop techniques sont clarifiés, et le catalogue des fournisseurs se met à jour tout seul. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useRef } from 'react'
|
||||
import { motion, AnimatePresence } from 'motion/react'
|
||||
import { Search, Bot, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react'
|
||||
import { Search, Bot, ChevronLeft, ChevronRight, Loader2, Check } from 'lucide-react'
|
||||
import { useLanguage } from '@/lib/i18n'
|
||||
import { DashboardWidgetTitleRow } from '@/components/dashboard-widget-title-row'
|
||||
|
||||
@@ -14,6 +14,11 @@ export interface AgentSuggestion {
|
||||
suggestedFrequency: string
|
||||
}
|
||||
|
||||
export interface CreatedAgentNotice {
|
||||
id: string | null
|
||||
topic: string
|
||||
}
|
||||
|
||||
export interface DashboardAgentCarouselProps {
|
||||
suggestions: AgentSuggestion[]
|
||||
loading?: boolean
|
||||
@@ -21,6 +26,9 @@ export interface DashboardAgentCarouselProps {
|
||||
formatFrequency: (f: string) => string
|
||||
onAccept: (id: string) => void
|
||||
onDismiss: (id: string) => void
|
||||
createdAgent?: CreatedAgentNotice | null
|
||||
onOpenCreated?: () => void
|
||||
onClearCreated?: () => void
|
||||
prefersReducedMotion?: boolean
|
||||
}
|
||||
|
||||
@@ -31,11 +39,15 @@ export function DashboardAgentCarousel({
|
||||
formatFrequency,
|
||||
onAccept,
|
||||
onDismiss,
|
||||
createdAgent,
|
||||
onOpenCreated,
|
||||
onClearCreated,
|
||||
prefersReducedMotion,
|
||||
}: DashboardAgentCarouselProps) {
|
||||
const { t } = useLanguage()
|
||||
const [idx, setIdx] = useState(0)
|
||||
const directionRef = useRef(1)
|
||||
const safeIdx = suggestions.length === 0 ? 0 : Math.min(idx, suggestions.length - 1)
|
||||
|
||||
const goPrev = () => {
|
||||
directionRef.current = -1
|
||||
@@ -46,24 +58,27 @@ export function DashboardAgentCarousel({
|
||||
setIdx(i => Math.min(suggestions.length - 1, i + 1))
|
||||
}
|
||||
|
||||
const navActions = suggestions.length > 1 ? (
|
||||
const showCreated = !!createdAgent
|
||||
const showNav = !showCreated && suggestions.length > 1
|
||||
|
||||
const navActions = showNav ? (
|
||||
<div className="flex items-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={goPrev}
|
||||
disabled={idx === 0}
|
||||
disabled={safeIdx === 0}
|
||||
className="p-1 rounded border border-border/30 disabled:opacity-25"
|
||||
aria-label={t('homeDashboard.intelPrev')}
|
||||
>
|
||||
<ChevronLeft size={12} />
|
||||
</button>
|
||||
<span className="text-[8px] font-mono text-concrete px-1">
|
||||
{idx + 1}/{suggestions.length}
|
||||
{safeIdx + 1}/{suggestions.length}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={goNext}
|
||||
disabled={idx >= suggestions.length - 1}
|
||||
disabled={safeIdx >= suggestions.length - 1}
|
||||
className="p-1 rounded border border-border/30 disabled:opacity-25"
|
||||
aria-label={t('homeDashboard.intelNext')}
|
||||
>
|
||||
@@ -83,9 +98,18 @@ export function DashboardAgentCarousel({
|
||||
icon={<Bot size={12} className="text-brand-accent" />}
|
||||
title={t('homeDashboard.suggestedResearch')}
|
||||
actions={navActions}
|
||||
wrapTitle
|
||||
/>
|
||||
|
||||
{suggestions.length === 0 ? (
|
||||
{showCreated && createdAgent ? (
|
||||
<CreatedAgentPanel
|
||||
topic={createdAgent.topic}
|
||||
hasMore={suggestions.length > 0}
|
||||
onOpen={onOpenCreated}
|
||||
onSeeNext={onClearCreated}
|
||||
t={t}
|
||||
/>
|
||||
) : suggestions.length === 0 ? (
|
||||
<div className="rounded-xl border border-dashed border-border/35 bg-stone-50/50 dark:bg-zinc-950/30 p-3">
|
||||
<p className="text-[11px] text-concrete leading-relaxed">
|
||||
{t('homeDashboard.agentsEmpty')}
|
||||
@@ -93,7 +117,7 @@ export function DashboardAgentCarousel({
|
||||
</div>
|
||||
) : (
|
||||
<AgentSlide
|
||||
current={suggestions[idx]}
|
||||
current={suggestions[safeIdx]}
|
||||
direction={directionRef.current}
|
||||
actingId={actingId}
|
||||
formatFrequency={formatFrequency}
|
||||
@@ -107,6 +131,54 @@ export function DashboardAgentCarousel({
|
||||
)
|
||||
}
|
||||
|
||||
function CreatedAgentPanel({
|
||||
topic,
|
||||
hasMore,
|
||||
onOpen,
|
||||
onSeeNext,
|
||||
t,
|
||||
}: {
|
||||
topic: string
|
||||
hasMore: boolean
|
||||
onOpen?: () => void
|
||||
onSeeNext?: () => void
|
||||
t: (key: string) => string
|
||||
}) {
|
||||
return (
|
||||
<div className="p-3.5 rounded-xl border border-border/25 bg-stone-50/60 dark:bg-zinc-950/40">
|
||||
<div className="flex items-start gap-2 mb-2">
|
||||
<Check size={14} className="text-brand-accent shrink-0 mt-0.5" />
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-semibold text-ink dark:text-dark-ink leading-snug">
|
||||
{t('homeDashboard.agentCreatedInCard')}
|
||||
</p>
|
||||
{topic ? (
|
||||
<p className="text-[11px] text-concrete leading-relaxed mt-1">{topic}</p>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2 mt-3">
|
||||
{hasMore && onSeeNext ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onSeeNext}
|
||||
className="text-[9px] font-mono uppercase px-2.5 py-1.5 rounded-lg border border-border/40 text-concrete hover:text-ink transition-colors"
|
||||
>
|
||||
{t('homeDashboard.agentSeeNextSuggestion')}
|
||||
</button>
|
||||
) : null}
|
||||
<button
|
||||
type="button"
|
||||
onClick={onOpen}
|
||||
className="flex-1 inline-flex items-center justify-center gap-1 text-[9px] font-mono uppercase px-2.5 py-1.5 rounded-lg bg-brand-accent text-white font-bold hover:bg-brand-accent/90"
|
||||
>
|
||||
{t('homeDashboard.agentOpenCreated')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function AgentSlide({
|
||||
current,
|
||||
direction,
|
||||
@@ -165,7 +237,7 @@ function AgentSlide({
|
||||
type="button"
|
||||
disabled={actingId === current.id}
|
||||
onClick={() => onAccept(current.id)}
|
||||
className="flex-1 inline-flex items-center justify-center gap-1 text-[9px] font-mono uppercase px-2.5 py-1.5 rounded-lg bg-ink text-white dark:bg-white dark:text-black font-bold hover:opacity-90 disabled:opacity-40"
|
||||
className="flex-1 inline-flex items-center justify-center gap-1 text-[9px] font-mono uppercase px-2.5 py-1.5 rounded-lg bg-brand-accent text-white font-bold hover:bg-brand-accent/90 disabled:opacity-40"
|
||||
>
|
||||
{actingId === current.id ? <Loader2 size={10} className="animate-spin" /> : null}
|
||||
{t('homeDashboard.createAgent')}
|
||||
|
||||
Reference in New Issue
Block a user