Spaces:
Configuration error
Configuration error
| import React, { useState, useCallback } from 'react'; | |
| import { CaseIntakeForm } from './components/CaseIntakeForm'; | |
| import { ActionPlanComponent } from './components/ActionPlan'; | |
| import { generateActionPlan } from './services/geminiService'; | |
| import type { ActionPlan, CaseData, ActionItemStatus } from './types'; | |
| import { Spinner } from './components/icons/Spinner'; | |
| const App: React.FC = () => { | |
| const [view, setView] = useState<'form' | 'plan'>('form'); | |
| const [actionPlan, setActionPlan] = useState<ActionPlan | null>(null); | |
| const [isLoading, setIsLoading] = useState<boolean>(false); | |
| const [error, setError] = useState<string | null>(null); | |
| const handleFormSubmit = useCallback(async (data: CaseData) => { | |
| setIsLoading(true); | |
| setError(null); | |
| try { | |
| const plan = await generateActionPlan(data); | |
| setActionPlan(plan); | |
| setView('plan'); | |
| } catch (err) { | |
| console.error(err); | |
| setError('Failed to generate an action plan. Please check your API key and try again.'); | |
| } finally { | |
| setIsLoading(false); | |
| } | |
| }, []); | |
| const handleToggleItem = useCallback((categoryIndex: number, itemIndex: number) => { | |
| setActionPlan(prevPlan => { | |
| if (!prevPlan) return null; | |
| const newPlan = JSON.parse(JSON.stringify(prevPlan)); | |
| const currentStatus = newPlan.categories[categoryIndex].items[itemIndex].status; | |
| const newStatus: ActionItemStatus = currentStatus === 'Completed' ? 'Not Started' : 'Completed'; | |
| newPlan.categories[categoryIndex].items[itemIndex].status = newStatus; | |
| return newPlan; | |
| }); | |
| }, []); | |
| const handleReset = useCallback(() => { | |
| setView('form'); | |
| setActionPlan(null); | |
| setError(null); | |
| }, []); | |
| return ( | |
| <div className="min-h-screen bg-gray-950"> | |
| <div className="relative isolate overflow-hidden"> | |
| <svg | |
| className="absolute inset-0 -z-10 h-full w-full stroke-white/10 [mask-image:radial-gradient(100%_100%_at_top_right,white,transparent)]" | |
| aria-hidden="true" | |
| > | |
| <defs> | |
| <pattern | |
| id="983e3e4c-de6d-4c3f-8d64-b9761d1534cc" | |
| width={200} | |
| height={200} | |
| x="50%" | |
| y={-1} | |
| patternUnits="userSpaceOnUse" | |
| > | |
| <path d="M.5 200V.5H200" fill="none" /> | |
| </pattern> | |
| </defs> | |
| <svg x="50%" y={-1} className="overflow-visible fill-gray-800/20"> | |
| <path | |
| d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z" | |
| strokeWidth={0} | |
| /> | |
| </svg> | |
| <rect width="100%" height="100%" strokeWidth={0} fill="url(#983e3e4c-de6d-4c3f-8d64-b9761d1534cc)" /> | |
| </svg> | |
| </div> | |
| <main className="container mx-auto px-4 py-8 md:py-16"> | |
| <header className="text-center mb-12"> | |
| <h1 className="font-display text-4xl md:text-6xl font-bold tracking-tight text-white"> | |
| SSDI Case Prep <span className="text-brand-secondary">Assistant</span> | |
| </h1> | |
| <p className="mt-4 text-lg text-gray-400 max-w-2xl mx-auto"> | |
| Your AI-powered guide to organizing and strengthening your Social Security Disability claim. | |
| </p> | |
| </header> | |
| {isLoading && ( | |
| <div className="fixed inset-0 bg-gray-950 bg-opacity-80 flex flex-col items-center justify-center z-50"> | |
| <Spinner /> | |
| <p className="mt-4 text-white text-lg font-medium">Generating your personalized action plan...</p> | |
| <p className="mt-2 text-gray-400">This may take a moment. The AI is analyzing your case details.</p> | |
| </div> | |
| )} | |
| {error && ( | |
| <div className="bg-red-900/50 border border-red-700 text-red-300 px-4 py-3 rounded-lg relative max-w-2xl mx-auto" role="alert"> | |
| <strong className="font-bold">Error: </strong> | |
| <span className="block sm:inline">{error}</span> | |
| </div> | |
| )} | |
| <div className="max-w-4xl mx-auto"> | |
| {view === 'form' && !actionPlan ? ( | |
| <CaseIntakeForm onSubmit={handleFormSubmit} /> | |
| ) : ( | |
| actionPlan && <ActionPlanComponent plan={actionPlan} onToggleItem={handleToggleItem} onReset={handleReset} /> | |
| )} | |
| </div> | |
| </main> | |
| <footer className="text-center py-8 text-gray-500"> | |
| <p>© {new Date().getFullYear()} SSDI Case Prep Assistant. All Rights Reserved.</p> | |
| </footer> | |
| </div> | |
| ); | |
| }; | |
| export default App; | |