Files
audiobook/frontend/src/components/TextInputSection.tsx
Paul Bailey fb294252c7 feat: create stunning premium UI with advanced design elements
- Add animated gradient backgrounds with floating particles
- Implement advanced glass morphism with enhanced blur effects
- Add Google Fonts Inter for professional typography
- Create sophisticated button animations with ripple effects
- Add progress indicator dots showing current step
- Implement card hover effects with smooth transforms
- Add animated gradient text with shimmer effects
- Create premium loading spinners with dual rings
- Add character counter to textarea
- Implement numbered badges for roles and segments
- Add gradient backgrounds to all cards and sections
- Create pulsing glow animations for important elements
- Add emoji icons throughout for visual appeal
- Implement responsive grid layouts for settings
- Add detailed subtitles and descriptions to sections
- Create success celebration with bouncing animation
- Add shadow effects with color-matched glows
- Implement smooth transitions and cubic-bezier easing
- Add visual hierarchy with varied font weights
- Create immersive, modern user experience
2025-12-09 13:20:20 +00:00

105 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react';
interface TextInputSectionProps {
text: string;
onChange: (text: string) => void;
onNext: () => void;
isLoading: boolean;
disabled: boolean;
}
export default function TextInputSection({
text,
onChange,
onNext,
isLoading,
disabled
}: TextInputSectionProps) {
const [showValidation, setShowValidation] = useState(false);
const handleNext = () => {
if (text.trim() === '') {
setShowValidation(true);
return;
}
setShowValidation(false);
onNext();
};
const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
onChange(e.target.value);
if (e.target.value.trim() !== '') {
setShowValidation(false);
}
};
const isButtonDisabled = disabled || isLoading || text.trim() === '';
return (
<div className="w-full max-w-4xl mx-auto p-6 sm:p-8 glass-effect rounded-3xl shadow-glow card-hover">
<div className="flex items-center gap-4 mb-6 sm:mb-8">
<div className="w-14 h-14 bg-gradient-to-br from-purple-500 via-purple-600 to-indigo-600 rounded-2xl flex items-center justify-center shadow-lg shadow-purple-500/50">
<span className="text-2xl">📝</span>
</div>
<div>
<h2 className="text-2xl sm:text-3xl font-extrabold gradient-text-animated">Enter Your Text</h2>
<p className="text-gray-600 text-sm mt-1">Paste or type your story below</p>
</div>
</div>
<div className="mb-6 relative">
<textarea
value={text}
onChange={handleTextChange}
placeholder="Enter your text here. Use patterns like 'Name:' or '[Name]' to mark different speakers...
Example:
Sarah: Hello! How are you today?
John: I'm doing great, thanks for asking!"
className="w-full h-72 sm:h-80 md:h-96 p-5 sm:p-6 border-2 border-purple-300 rounded-2xl focus:border-purple-600 focus:ring-4 focus:ring-purple-300 focus:outline-none resize-y text-sm sm:text-base touch-manipulation shadow-inner bg-gradient-to-br from-white to-purple-50/30 font-mono leading-relaxed"
disabled={disabled || isLoading}
/>
<div className="absolute bottom-4 right-4 text-xs text-gray-500 bg-white/80 px-3 py-1 rounded-lg backdrop-blur-sm">
{text.length} characters
</div>
</div>
{showValidation && text.trim() === '' && (
<div className="mb-6 p-4 sm:p-5 bg-gradient-to-r from-red-50 to-pink-50 border-2 border-red-400 text-red-700 rounded-2xl shadow-lg text-sm sm:text-base animate-pulse">
<div className="flex items-center gap-3">
<span className="text-2xl">⚠️</span>
<p className="font-bold">Please enter some text before proceeding.</p>
</div>
</div>
)}
<div className="flex justify-center">
<button
onClick={handleNext}
disabled={isButtonDisabled}
className={`px-10 py-5 min-h-[56px] rounded-2xl font-bold text-white text-lg transition-all touch-manipulation shadow-2xl relative overflow-hidden ${
isButtonDisabled
? 'bg-gray-400 cursor-not-allowed opacity-60'
: 'bg-gradient-to-r from-purple-600 via-purple-700 to-indigo-600 hover:from-purple-700 hover:via-purple-800 hover:to-indigo-700 cursor-pointer shadow-purple-500/50'
}`}
>
{isLoading ? (
<span className="flex items-center justify-center gap-3 relative z-10">
<div className="relative">
<div className="animate-spin rounded-full h-6 w-6 border-3 border-white/30"></div>
<div className="animate-spin rounded-full h-6 w-6 border-3 border-white border-t-transparent absolute top-0 left-0"></div>
</div>
Processing...
</span>
) : (
<span className="flex items-center justify-center gap-3 relative z-10">
Next: Assign Voices
<span className="text-xl">→</span>
</span>
)}
</button>
</div>
</div>
);
}