DocDoeAI / src /components /learn-anything /LearnAnythingErrorState.tsx
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
3.07 kB
"use client";
import { useMemo } from "react";
import { getCoursePlanGenerationErrorMessage, type CoursePlanGenerationError } from "./coursePlanApi";
interface LearnAnythingErrorStateProps {
error: CoursePlanGenerationError;
isGenerating: boolean;
onRetry: () => void;
canRetry: boolean;
}
/**
* Error state display for the course-plan flow.
* Shows appropriate error messages and retry options based on error type.
*/
export function LearnAnythingErrorState({
error,
isGenerating,
onRetry,
canRetry,
}: LearnAnythingErrorStateProps) {
const message = useMemo(() => getCoursePlanGenerationErrorMessage(error), [error]);
// Determine error type for styling
const isAuthError = error.kind === "auth";
const isRateLimitError = error.kind === "rate-limit";
const isNetworkOrServerError = error.kind === "network" || error.kind === "server" || error.kind === "unknown";
return (
<div
className={`rounded-xl border p-4 ${isAuthError ? "border-yellow-500/30 bg-yellow-500/[0.05]" : isRateLimitError ? "border-orange-500/30 bg-orange-500/[0.05]" : "border-white/10 bg-white/[0.04]"}`}
aria-live="polite"
>
{/* Error Message */}
<p className={`text-sm ${isAuthError ? "text-yellow-400" : isRateLimitError ? "text-orange-400" : "text-white/75"}`}>
{message}
</p>
{/* Additional context for certain errors */}
{isAuthError && (
<p className="mt-2 text-xs text-white/45">
Authentication required to generate course plans
</p>
)}
{isRateLimitError && (
<p className="mt-2 text-xs text-white/45">
Free generation limit reached for now
</p>
)}
{/* Retry button - only shown for retryable errors */}
{canRetry && !isGenerating && (
<div className="mt-4">
<button
type="button"
onClick={onRetry}
disabled={isGenerating}
className="rounded-lg border border-white/15 px-4 py-2 text-sm text-white/75 transition-colors hover:bg-white/10 disabled:opacity-50"
>
{isGenerating ? "Retrying..." : "Retry generation"}
</button>
</div>
)}
{/* No retry for auth errors - just informational */}
{isAuthError && !canRetry && (
<div className="mt-4">
<p className="text-xs text-white/40">
Please sign in to access course plan generation
</p>
</div>
)}
{/* No retry for rate limit - just informational */}
{isRateLimitError && !canRetry && (
<div className="mt-4">
<p className="text-xs text-white/40">
Your starter outline is still available above
</p>
</div>
)}
{/* For other errors, show saved request info if available */}
{isNetworkOrServerError && error.status && (
<p className="mt-2 text-xs text-white/40">
Error code: {error.status}
{error.retryAfter && ` - Retry in ${error.retryAfter}s`}
</p>
)}
</div>
);
}