Description
Accounts receivable staff often maintain invoice data in spreadsheets and want to quickly create a single StellarSplit invoice from a CSV row without the existing bulk-import flow (which requires many rows). This issue adds a "Import from CSV row" option to /invoice/new that parses a user-pasted CSV row (or a single-row file upload) against a documented column schema, maps fields to invoice form values, and pre-populates the form for the user to review and submit. Column mapping is configurable to support different spreadsheet layouts.
Technical Context
Create components/invoice/CSVRowImporter.tsx as a collapsible panel on app/invoice/new/page.tsx. The panel offers two input modes: (1) paste a CSV row with headers, (2) drag-and-drop a single-row CSV file. Parse input using papaparse with header: true. Define the expected schema in lib/csvInvoiceSchema.ts mapping CSV column names to InvoiceFormFields. Build a ColumnMappingModal that appears when the uploaded CSV has column names that do not match the expected schema; users drag-and-drop column names to map them. Validate parsed values with zod before calling form.reset(). Persist column mappings in localStorage so repeat imports from the same spreadsheet layout skip the mapping step. Support multi-recipient import via pipe-delimited recipients column in the format address1:percent1|address2:percent2.
Acceptance Criteria
Description
Accounts receivable staff often maintain invoice data in spreadsheets and want to quickly create a single StellarSplit invoice from a CSV row without the existing bulk-import flow (which requires many rows). This issue adds a "Import from CSV row" option to
/invoice/newthat parses a user-pasted CSV row (or a single-row file upload) against a documented column schema, maps fields to invoice form values, and pre-populates the form for the user to review and submit. Column mapping is configurable to support different spreadsheet layouts.Technical Context
Create
components/invoice/CSVRowImporter.tsxas a collapsible panel onapp/invoice/new/page.tsx. The panel offers two input modes: (1) paste a CSV row with headers, (2) drag-and-drop a single-row CSV file. Parse input usingpapaparsewithheader: true. Define the expected schema inlib/csvInvoiceSchema.tsmapping CSV column names toInvoiceFormFields. Build aColumnMappingModalthat appears when the uploaded CSV has column names that do not match the expected schema; users drag-and-drop column names to map them. Validate parsed values withzodbefore callingform.reset(). Persist column mappings inlocalStorageso repeat imports from the same spreadsheet layout skip the mapping step. Support multi-recipient import via pipe-delimitedrecipientscolumn in the formataddress1:percent1|address2:percent2.Acceptance Criteria
ColumnMappingModalappears and the user can map columns; the mapping is saved and reused on subsequent importsrecipientscolumn correctly parses into multipleRecipientLineentries with the correct addresses and percentages