@@ -46,7 +46,14 @@ export function App() {
4646 const [ fields , setFields ] = useState < TemplateField [ ] > ( [ ] ) ;
4747 const [ events , setEvents ] = useState < string [ ] > ( [ ] ) ;
4848 const [ isDownloading , setIsDownloading ] = useState ( false ) ;
49+ const [ isImporting , setIsImporting ] = useState ( false ) ;
50+ const [ importError , setImportError ] = useState < string | null > ( null ) ;
51+ const [ documentSource , setDocumentSource ] = useState < string | File > (
52+ "https://storage.googleapis.com/public_static_hosting/public_demo_docs/service_agreement.docx" ,
53+ ) ;
4954 const builderRef = useRef < SuperDocTemplateBuilderHandle > ( null ) ;
55+ const fileInputRef = useRef < HTMLInputElement > ( null ) ;
56+ const importingRef = useRef ( false ) ;
5057
5158 const log = useCallback ( ( msg : string ) => {
5259 const time = new Date ( ) . toLocaleTimeString ( ) ;
@@ -75,6 +82,12 @@ export function App() {
7582
7683 const handleReady = useCallback ( ( ) => {
7784 log ( '✓ Template builder ready' ) ;
85+ if ( importingRef . current ) {
86+ log ( '📄 Document imported' ) ;
87+ importingRef . current = false ;
88+ setImportError ( null ) ;
89+ setIsImporting ( false ) ;
90+ }
7891 } , [ log ] ) ;
7992
8093 const handleTrigger = useCallback ( ( ) => {
@@ -114,9 +127,35 @@ export function App() {
114127 } ;
115128
116129 const documentConfig = useMemo ( ( ) => ( {
117- source : "https://storage.googleapis.com/public_static_hosting/public_demo_docs/service_agreement.docx" ,
130+ source : documentSource ,
118131 mode : 'editing' as const
119- } ) , [ ] ) ;
132+ } ) , [ documentSource ] ) ;
133+
134+ const handleImportButtonClick = useCallback ( ( ) => {
135+ if ( isImporting ) return ;
136+ fileInputRef . current ?. click ( ) ;
137+ } , [ isImporting ] ) ;
138+
139+ const handleFileInputChange = useCallback ( ( event : React . ChangeEvent < HTMLInputElement > ) => {
140+ const file = event . target . files ?. [ 0 ] ;
141+ event . target . value = "" ;
142+
143+ if ( ! file ) return ;
144+
145+ const extension = file . name . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
146+ if ( extension !== 'docx' ) {
147+ const message = 'Invalid file type. Please choose a .docx file.' ;
148+ setImportError ( message ) ;
149+ log ( '⚠️ ' + message ) ;
150+ return ;
151+ }
152+
153+ importingRef . current = true ;
154+ setImportError ( null ) ;
155+ setIsImporting ( true ) ;
156+ setDocumentSource ( file ) ;
157+ log ( `📥 Importing "${ file . name } "` ) ;
158+ } , [ log ] ) ;
120159
121160 const fieldsConfig = useMemo ( ( ) => ( {
122161 available : availableFields ,
@@ -160,16 +199,36 @@ export function App() {
160199 < span className = "hint" > Tab/Shift+Tab to navigate</ span >
161200 </ div >
162201 < div className = "toolbar-right" >
202+ < input
203+ type = "file"
204+ accept = ".docx"
205+ ref = { fileInputRef }
206+ style = { { display : 'none' } }
207+ onChange = { handleFileInputChange }
208+ />
209+ < button
210+ onClick = { handleImportButtonClick }
211+ className = "import-button"
212+ disabled = { isImporting || isDownloading }
213+ >
214+ { isImporting ? 'Importing…' : 'Import File' }
215+ </ button >
163216 < button
164217 onClick = { handleExportTemplate }
165218 className = "export-button"
166- disabled = { isDownloading }
219+ disabled = { isDownloading || isImporting }
167220 >
168221 { isDownloading ? "Exporting..." : "Export Template" }
169222 </ button >
170223 </ div >
171224 </ div >
172225
226+ { importError && (
227+ < div className = "toolbar-error" role = "alert" >
228+ { importError }
229+ </ div >
230+ ) }
231+
173232 < SuperDocTemplateBuilder
174233 ref = { builderRef }
175234 document = { documentConfig }
0 commit comments