The list import feature allows users to import grocery lists from external files in multiple formats (JSON, CSV, and plain text). This feature complements the existing export functionality and provides a seamless way to migrate data or create lists from external sources.
Purpose: Core import logic with format parsers and validation
Key Functions:
importFromJSON(file)- Parses JSON files with full item detailsimportFromCSV(file)- Parses CSV files with spreadsheet compatibilityimportFromText(file)- Parses plain text files (simplest format)importList(file)- Auto-detects format and routes to appropriate parser
Features:
- Comprehensive validation for item names, quantities, and categories
- Category normalization with fallback to "Other"
- Error collection for invalid items while allowing partial imports
- Warning system for data normalization and missing fields
- File size validation (5MB limit)
- Support for quantity prefixes in text format (e.g., "2 Apples", "3x Bananas")
TypeScript Types:
interface ImportedItem {
name: string;
quantity: number;
category: Category;
notes: string;
}
interface ImportResult {
success: boolean;
listName: string;
items: ImportedItem[];
errors: string[];
warnings: string[];
}Purpose: User interface component for file import with preview
Key Features:
-
File Upload Interface:
- Drag-and-drop support
- Click-to-browse file picker
- File type filtering (.json, .csv, .txt)
-
Multi-Step Workflow:
- Step 1: File selection with format guide
- Step 2: Preview imported items with validation feedback
- Step 3: Loading state during import
- Step 4: Success confirmation
-
Preview Functionality:
- Shows item count and details
- Editable list name
- Displays warnings and errors
- Category-coded item display
- Scrollable item list with metadata
-
Error Handling:
- Clear error messages for invalid files
- Warnings for normalized data
- Partial import support (shows which items failed)
Props:
interface ImportListProps {
onClose: () => void;
onImportComplete?: (listId: string) => void;
}Purpose: Comprehensive styling for the import modal
Key Styling:
- Modal overlay with backdrop blur
- Responsive design (mobile-friendly)
- Category-coded badges with colors matching existing system
- Smooth animations (fadeIn, slideUp, spin)
- File drop zone with hover effects
- Error/warning/success message styling
- Preview item list with scrolling
- Format guide examples with code blocks
Design Features:
- Consistent with existing app design system
- Accessible button states and focus indicators
- Mobile-responsive layout adaptations
- Visual feedback for all user interactions
Changes:
- Added ImportList component import
- Added
showImportstate for modal visibility - Added "Import" button next to "Create List" button
- Added
handleImportCompletecallback to navigate to imported list - Integrated ImportList modal at component bottom
New Button:
<button
className="btn btn-secondary import-list-btn"
onClick={() => setShowImport(true)}
title="Import list from file"
>
<svg>...</svg>
Import
</button>Changes:
- Added
.import-list-btnstyles for consistent button appearance
{
"name": "Weekly Groceries",
"items": [
{
"name": "Milk",
"quantity": 2,
"category": "Dairy",
"notes": "Whole milk"
}
]
}Features:
- Full control over all properties
- Structured validation
- Supports list name and notes
name,quantity,category,notes
Milk,2,Dairy,Whole milk
Apples,6,Produce,Features:
- Spreadsheet compatibility
- Header row required
- Empty fields allowed
- List name from filename
Milk
2 Apples
3x Bananas
Features:
- Simplest format
- Optional quantity prefix
- All items default to "Other" category
- List name from filename
All imported items must use one of these categories (case-insensitive):
- Produce
- Dairy
- Meat
- Bakery
- Pantry
- Frozen
- Beverages
- Other (default fallback)
-
Item Name:
- Cannot be empty
- Maximum 200 characters
- Leading/trailing whitespace trimmed
-
Quantity:
- Must be positive number
- Defaults to 1 if invalid
- Rounded to integer
-
Category:
- Normalized to valid category
- Case-insensitive matching
- Falls back to "Other" if unrecognized
-
File Size:
- Maximum 5MB per file
- Graceful Degradation: Valid items are imported even if some fail
- Clear Feedback: Line numbers and specific error messages
- Warnings: Non-critical issues (e.g., category normalization)
- Partial Success: Shows count of successful vs. failed items
- Uses
createListFromTemplate()fromuseListMutations() - Automatically associates items with authenticated user
- Maintains consistency with existing list creation flow
- Import button placed alongside "Create List" button
- Modal overlay prevents interaction with background
- Success callback navigates to newly imported list
- Close button returns to dashboard
- All imports properly typed with TypeScript
- Reuses existing
CategoryandGroceryItemtypes - Type-safe file parsing and validation
-
Initiation:
- User clicks "Import" button in List Dashboard
- Modal opens with file selection interface
-
File Selection:
- User drags file or clicks to browse
- Format guide shown for reference
- File is immediately parsed and validated
-
Preview:
- Shows item count and details
- Displays any warnings or errors
- User can edit list name
- User reviews and confirms import
-
Import:
- Loading spinner during list creation
- Items are created in Zero store
- Success message shown
-
Completion:
- Modal auto-closes after brief delay
- User navigated to new list automatically
Created sample import files in /home/adam/grocery/sample-imports/:
example-list.json- Full-featured JSON exampleexample-list.csv- Spreadsheet-compatible CSV exampleexample-list.txt- Simple text format exampleREADME.md- Comprehensive format documentation
-
Format Testing:
- Test all three file formats
- Verify category normalization
- Test quantity prefix parsing (text format)
-
Validation Testing:
- Empty files
- Invalid JSON structure
- Missing required fields
- Oversized files (>5MB)
- Invalid categories
- Special characters in names
-
Error Handling:
- Partial file with some invalid items
- Files with warnings (normalized data)
- Network failures during import
-
UI Testing:
- Drag-and-drop functionality
- Mobile responsiveness
- Modal overlay interaction
- Button states and feedback
-
Integration Testing:
- Imported lists appear in dashboard
- Items correctly associated with user
- Navigation to imported list works
- Close/cancel functionality
- Semantic HTML structure
- ARIA labels for icon buttons
- Keyboard navigation support
- Focus management in modal
- Screen reader friendly error messages
- High contrast for visual elements
- File parsing is asynchronous
- Large files handled with streaming where possible
- Preview list virtualization for many items
- Efficient validation with early returns
- Minimal re-renders with proper state management
-
Format Extensions:
- Excel (.xlsx) format support
- Google Sheets direct import
- Barcode scanning integration
-
Advanced Features:
- Duplicate detection
- Merge with existing list option
- Import history/undo
- Bulk import multiple files
-
UI Improvements:
- Item editing in preview
- Category auto-suggestion
- Import templates library
- Drag to reorder items
-
Validation Enhancements:
- Smart category detection
- Nutrition data parsing
- Price information import
- Store location mapping
The list import feature provides a robust, user-friendly way to import grocery lists from various file formats. It includes:
- 3 file formats supported (JSON, CSV, TXT)
- Comprehensive validation with helpful error messages
- Graceful error handling allowing partial imports
- Beautiful UI with drag-and-drop and preview
- Type-safe implementation with full TypeScript support
- Seamless integration with existing Zero store and authentication
- Sample files and documentation for user guidance
All TypeScript types are validated and the feature is ready for production use.