From 85a71fac2c239abdad0d7ee265f36331450b4a62 Mon Sep 17 00:00:00 2001 From: Paul Bailey Date: Tue, 9 Dec 2025 07:39:36 +0000 Subject: [PATCH] Implement text input component (Task 9) - Create TextInputSection component with large multiline textarea - Add 'Next: Assign voices' button - Implement text validation (non-empty) - Show validation message for empty text - Disable button when text is empty - Update App.tsx to integrate TextInputSection - Requirements: 1.1, 1.2, 1.3, 1.4 --- frontend/src/App.tsx | 64 +++++++++++------- frontend/src/components/TextInputSection.tsx | 71 ++++++++++++++++++++ 2 files changed, 111 insertions(+), 24 deletions(-) create mode 100644 frontend/src/components/TextInputSection.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 3d7ded3..b36760d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,34 +1,50 @@ import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' import './App.css' +import TextInputSection from './components/TextInputSection' function App() { - const [count, setCount] = useState(0) + const [text, setText] = useState('') + const [phase, setPhase] = useState<'input' | 'assignment' | 'generated'>('input') + const [isLoading] = useState(false) + + const handleTextChange = (newText: string) => { + setText(newText) + } + + const handleNext = () => { + // TODO: Implement role detection and phase transition + console.log('Moving to voice assignment phase with text:', text) + setPhase('assignment') + } return ( - <> -
- - Vite logo - - - React logo - +
+
+

Text to Audiobook

+ + {phase === 'input' && ( + + )} + + {phase === 'assignment' && ( +
+

Voice assignment phase (to be implemented)

+
+ )} + + {phase === 'generated' && ( +
+

Audio player phase (to be implemented)

+
+ )}
-

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

- +
) } diff --git a/frontend/src/components/TextInputSection.tsx b/frontend/src/components/TextInputSection.tsx new file mode 100644 index 0000000..39a6607 --- /dev/null +++ b/frontend/src/components/TextInputSection.tsx @@ -0,0 +1,71 @@ +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) => { + onChange(e.target.value); + if (e.target.value.trim() !== '') { + setShowValidation(false); + } + }; + + const isButtonDisabled = disabled || isLoading || text.trim() === ''; + + return ( +
+

Enter Your Text

+ +
+