feat(05-03): frontend fallback integration for research display
- ExerciseResearchPanel: add ProviderBadge component showing which AI tier (Ollama/Gemini/OpenRouter/OpenCode/Exa) served the response - Add auto-retry on 429/503 with 2s delay and retry counter in button - Normalize error messages for common failure modes (network, rate-limit) - ResearchDisplay: pass onRetry prop to error state for inline retry button - CSS: .research-panel-controls flex row, .provider-badge with per-provider colour coding, .rd-error-actions + .rd-retry button styles
This commit is contained in:
@@ -9,16 +9,23 @@ function ResearchLoadingSkeleton({ exerciseName }) {
|
||||
)
|
||||
}
|
||||
|
||||
function ResearchError({ message, onDismiss }) {
|
||||
function ResearchError({ message, onDismiss, onRetry }) {
|
||||
return (
|
||||
<div className="rd-error" role="alert">
|
||||
<span className="rd-error-icon" aria-hidden="true">⚠</span>
|
||||
<span className="rd-error-message">{message}</span>
|
||||
{onDismiss && (
|
||||
<button className="rd-dismiss" onClick={onDismiss} aria-label="Dismiss error">
|
||||
×
|
||||
</button>
|
||||
)}
|
||||
<div className="rd-error-actions">
|
||||
{onRetry && (
|
||||
<button className="rd-retry btn btn-sm btn-primary" onClick={onRetry}>
|
||||
Retry
|
||||
</button>
|
||||
)}
|
||||
{onDismiss && (
|
||||
<button className="rd-dismiss" onClick={onDismiss} aria-label="Dismiss error">
|
||||
×
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -52,14 +59,15 @@ function ResearchSourceCard({ result, index }) {
|
||||
* data {object} Research data: { summary, results }
|
||||
* name {string} Exercise name (shown during loading)
|
||||
* onDismiss {function} Clear error callback
|
||||
* onRetry {function} Retry fetch callback
|
||||
*/
|
||||
function ResearchDisplay({ loading, error, data, name, onDismiss }) {
|
||||
function ResearchDisplay({ loading, error, data, name, onDismiss, onRetry }) {
|
||||
if (loading) {
|
||||
return <ResearchLoadingSkeleton exerciseName={name} />
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <ResearchError message={error} onDismiss={onDismiss} />
|
||||
return <ResearchError message={error} onDismiss={onDismiss} onRetry={onRetry} />
|
||||
}
|
||||
|
||||
if (!data) return null
|
||||
|
||||
Reference in New Issue
Block a user