Download src/components/learn-anything/LearnAnythingErrorState.tsx from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 3.07 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/learn-anything/LearnAnythingErrorState.tsx
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/learn-anything/LearnAnythingErrorState.tsx
-
curl -L -o LearnAnythingErrorState.tsx https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/learn-anything/LearnAnythingErrorState.tsx
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> | |
| ); | |
| } | |