Spaces:
Configuration error
Configuration error
File size: 3,833 Bytes
00e44ef | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | import React, { useState } from 'react';
import Header from './components/Header';
import SummaryResult from './components/SummaryResult';
import { summarizeText } from './services/gemini';
import { SummaryState } from './types';
const App: React.FC = () => {
const [state, setState] = useState<SummaryState>({
originalText: '',
summary: '',
isLoading: false,
error: null,
});
const handleSummarize = async () => {
if (!state.originalText.trim()) {
setState(prev => ({ ...prev, error: "Please enter some text to summarize." }));
return;
}
setState(prev => ({ ...prev, isLoading: true, error: null, summary: '' }));
try {
const summary = await summarizeText(state.originalText);
setState(prev => ({ ...prev, summary, isLoading: false }));
} catch (err) {
setState(prev => ({
...prev,
isLoading: false,
error: err instanceof Error ? err.message : "An unexpected error occurred."
}));
}
};
const handleClear = () => {
setState({
originalText: '',
summary: '',
isLoading: false,
error: null,
});
};
return (
<div className="min-h-screen flex flex-col">
<Header />
<main className="flex-grow py-12 px-4 bg-gray-50">
<div className="max-w-4xl mx-auto">
<div className="bg-white border border-gray-200 rounded-2xl p-6 shadow-sm transition-all focus-within:ring-2 focus-within:ring-indigo-100">
<div className="flex items-center justify-between mb-4">
<label htmlFor="inputText" className="text-sm font-semibold text-gray-700 uppercase tracking-wider">
Original Content
</label>
<div className="text-xs text-gray-400 font-medium">
{state.originalText.length} characters
</div>
</div>
<textarea
id="inputText"
className="w-full h-64 p-4 text-gray-800 placeholder-gray-400 border border-gray-100 rounded-xl resize-none focus:outline-none focus:border-indigo-200 bg-gray-50/50 transition-colors text-lg leading-relaxed"
placeholder="Paste the text you want to summarize..."
value={state.originalText}
onChange={(e) => setState(prev => ({ ...prev, originalText: e.target.value, error: null }))}
disabled={state.isLoading}
/>
<div className="mt-6 flex flex-col sm:flex-row gap-3">
<button
onClick={handleSummarize}
disabled={state.isLoading || !state.originalText.trim()}
className={`flex-grow h-12 flex items-center justify-center gap-2 px-6 rounded-xl font-bold text-white transition-all shadow-md active:scale-95 ${state.isLoading || !state.originalText.trim()
? 'bg-gray-300 cursor-not-allowed'
: 'bg-indigo-600 hover:bg-indigo-700 hover:shadow-indigo-200'
}`}
>
{state.isLoading ? 'Summarizing...' : 'Summarize Text'}
</button>
<button
onClick={handleClear}
disabled={state.isLoading || !state.originalText}
className="h-12 px-6 border border-gray-200 text-gray-600 font-semibold rounded-xl hover:bg-gray-50 transition-all disabled:opacity-50 active:scale-95"
>
Clear
</button>
</div>
{state.error && (
<div className="mt-4 p-4 bg-red-50 border border-red-100 text-red-700 text-sm font-medium rounded-xl">
{state.error}
</div>
)}
</div>
<SummaryResult summary={state.summary} />
</div>
</main>
</div>
);
};
export default App;
|