@@ -9,44 +9,38 @@ import "superdoc/dist/style.css";
99import "./App.css" ;
1010
1111const availableFields : FieldDefinition [ ] = [
12- // Contact Information
13- { id : "customer_name" , label : "Customer Name" , category : "Contact" } ,
14- { id : "customer_email" , label : "Customer Email" , category : "Contact" } ,
15- { id : "customer_phone" , label : "Customer Phone" , category : "Contact" } ,
16- { id : "customer_address" , label : "Customer Address" , category : "Contact" } ,
17-
18- // Company Information
19- { id : 'company_name' , label : 'Company Name' , category : 'Company' } ,
20- { id : 'company_address' , label : 'Company Address' , category : 'Company' } ,
21- { id : 'company_phone' , label : 'Company Phone' , category : 'Company' } ,
22- { id : 'company_email' , label : 'Company Email' , category : 'Company' } ,
23-
24- // Invoice/Order
25- { id : 'invoice_number' , label : 'Invoice Number' , category : 'Invoice' } ,
26- { id : 'invoice_date' , label : 'Invoice Date' , category : 'Invoice' } ,
27- { id : 'due_date' , label : 'Due Date' , category : 'Invoice' } ,
28- { id : 'total_amount' , label : 'Total Amount' , category : 'Invoice' } ,
29- { id : 'tax_amount' , label : 'Tax Amount' , category : 'Invoice' } ,
30- { id : 'subtotal' , label : 'Subtotal' , category : 'Invoice' } ,
12+ // Agreement
13+ { id : '1242142770' , label : 'Agreement Date' , category : 'Agreement' } ,
14+
15+ // Parties
16+ { id : '1242142771' , label : 'User Name' , category : 'Parties' } ,
17+ { id : '1242142772' , label : 'Company Name' , category : 'Parties' } ,
18+
19+ // Scope
20+ { id : '1242142773' , label : 'Service Type' , category : 'Scope' } ,
3121
3222 // Legal
33- { id : 'effective_date' , label : 'Effective Date' , category : 'Legal' } ,
34- { id : 'termination_date' , label : 'Termination Date' , category : 'Legal' } ,
35- { id : 'jurisdiction' , label : 'Jurisdiction' , category : 'Legal' } ,
36- { id : 'governing_law' , label : 'Governing Law' , category : 'Legal' } ,
37-
38- // Product/Service
39- { id : 'product_name' , label : 'Product Name' , category : 'Product' } ,
40- { id : 'product_description' , label : 'Product Description' , category : 'Product' } ,
41- { id : 'quantity' , label : 'Quantity' , category : 'Product' } ,
42- { id : 'unit_price' , label : 'Unit Price' , category : 'Product' } ,
23+ { id : '1242142774' , label : 'Agreement Jurisdiction' , category : 'Legal' } ,
24+
25+ // Company Details
26+ { id : '1242142775' , label : 'Company Address' , category : 'Company' } ,
27+
28+ // Signatures
29+ { id : '1242142776' , label : 'Signature' , category : 'Signatures' } ,
4330] ;
4431
4532export function App ( ) {
4633 const [ fields , setFields ] = useState < TemplateField [ ] > ( [ ] ) ;
4734 const [ events , setEvents ] = useState < string [ ] > ( [ ] ) ;
4835 const [ isDownloading , setIsDownloading ] = useState ( false ) ;
36+ const [ isImporting , setIsImporting ] = useState ( false ) ;
37+ const [ importError , setImportError ] = useState < string | null > ( null ) ;
38+ const [ documentSource , setDocumentSource ] = useState < string | File > (
39+ "https://storage.googleapis.com/public_static_hosting/public_demo_docs/new_service_agreement.docx" ,
40+ ) ;
4941 const builderRef = useRef < SuperDocTemplateBuilderHandle > ( null ) ;
42+ const fileInputRef = useRef < HTMLInputElement > ( null ) ;
43+ const importingRef = useRef ( false ) ;
5044
5145 const log = useCallback ( ( msg : string ) => {
5246 const time = new Date ( ) . toLocaleTimeString ( ) ;
@@ -63,7 +57,7 @@ export function App() {
6357 log ( `✓ Inserted: ${ field . alias } ` ) ;
6458 } , [ log ] ) ;
6559
66- const handleFieldDelete = useCallback ( ( fieldId : string ) => {
60+ const handleFieldDelete = useCallback ( ( fieldId : string | number ) => {
6761 log ( `✗ Deleted: ${ fieldId } ` ) ;
6862 } , [ log ] ) ;
6963
@@ -75,6 +69,12 @@ export function App() {
7569
7670 const handleReady = useCallback ( ( ) => {
7771 log ( '✓ Template builder ready' ) ;
72+ if ( importingRef . current ) {
73+ log ( '📄 Document imported' ) ;
74+ importingRef . current = false ;
75+ setImportError ( null ) ;
76+ setIsImporting ( false ) ;
77+ }
7878 } , [ log ] ) ;
7979
8080 const handleTrigger = useCallback ( ( ) => {
@@ -114,9 +114,35 @@ export function App() {
114114 } ;
115115
116116 const documentConfig = useMemo ( ( ) => ( {
117- source : "https://storage.googleapis.com/public_static_hosting/public_demo_docs/service_agreement.docx" ,
117+ source : documentSource ,
118118 mode : 'editing' as const
119- } ) , [ ] ) ;
119+ } ) , [ documentSource ] ) ;
120+
121+ const handleImportButtonClick = useCallback ( ( ) => {
122+ if ( isImporting ) return ;
123+ fileInputRef . current ?. click ( ) ;
124+ } , [ isImporting ] ) ;
125+
126+ const handleFileInputChange = useCallback ( ( event : React . ChangeEvent < HTMLInputElement > ) => {
127+ const file = event . target . files ?. [ 0 ] ;
128+ event . target . value = "" ;
129+
130+ if ( ! file ) return ;
131+
132+ const extension = file . name . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
133+ if ( extension !== 'docx' ) {
134+ const message = 'Invalid file type. Please choose a .docx file.' ;
135+ setImportError ( message ) ;
136+ log ( '⚠️ ' + message ) ;
137+ return ;
138+ }
139+
140+ importingRef . current = true ;
141+ setImportError ( null ) ;
142+ setIsImporting ( true ) ;
143+ setDocumentSource ( file ) ;
144+ log ( `📥 Importing "${ file . name } "` ) ;
145+ } , [ log ] ) ;
120146
121147 const fieldsConfig = useMemo ( ( ) => ( {
122148 available : availableFields ,
@@ -160,16 +186,36 @@ export function App() {
160186 < span className = "hint" > Tab/Shift+Tab to navigate</ span >
161187 </ div >
162188 < div className = "toolbar-right" >
189+ < input
190+ type = "file"
191+ accept = ".docx"
192+ ref = { fileInputRef }
193+ style = { { display : 'none' } }
194+ onChange = { handleFileInputChange }
195+ />
196+ < button
197+ onClick = { handleImportButtonClick }
198+ className = "import-button"
199+ disabled = { isImporting || isDownloading }
200+ >
201+ { isImporting ? 'Importing…' : 'Import File' }
202+ </ button >
163203 < button
164204 onClick = { handleExportTemplate }
165205 className = "export-button"
166- disabled = { isDownloading }
206+ disabled = { isDownloading || isImporting }
167207 >
168208 { isDownloading ? "Exporting..." : "Export Template" }
169209 </ button >
170210 </ div >
171211 </ div >
172212
213+ { importError && (
214+ < div className = "toolbar-error" role = "alert" >
215+ { importError }
216+ </ div >
217+ ) }
218+
173219 < SuperDocTemplateBuilder
174220 ref = { builderRef }
175221 document = { documentConfig }
0 commit comments