feat: add frontend import UI (refs #26)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-01-11 19:58:17 -06:00
parent 068db991a4
commit 7a5579df7b
7 changed files with 712 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
# User Data Import Feature
## Overview
Frontend implementation of user data import feature (issue #26, Milestone 4).
## Components
### ImportButton
**File**: `components/ImportButton.tsx`
- Opens file selector for .tar.gz files
- Client-side validation (file extension, size limit 500MB)
- Triggers ImportDialog on file selection
### ImportDialog
**File**: `components/ImportDialog.tsx`
- Multi-step wizard: Upload → Preview → Confirm → Progress → Results
- Step 1 (Upload): Shows selected file details
- Step 2 (Preview): Loading state while generating preview
- Step 3 (Confirm): Displays manifest, conflicts, mode selection (merge/replace)
- Step 4 (Progress): Shows import in progress
- Step 5 (Results): Displays summary with counts and any errors/warnings
- Responsive design for mobile (320px, 768px) and desktop (1920px)
- Touch targets >= 44px per CLAUDE.md requirement
### API Client
**File**: `api/import.api.ts`
- `getPreview(file)`: POST /api/user/import/preview (multipart)
- `executeImport(file, mode)`: POST /api/user/import (multipart)
- 2-minute timeout for large files
### React Query Hooks
**File**: `hooks/useImportUserData.ts`
- `useImportPreview()`: Mutation for preview generation
- `useImportUserData()`: Mutation for import execution
- Toast notifications for success/error states
### Types
**File**: `types/import.types.ts`
- `ImportManifest`: Archive contents and metadata
- `ImportPreview`: Preview data with conflicts
- `ImportResult`: Import execution results
- Mirrors backend types from `backend/src/features/user-import/domain/user-import.types.ts`
## Integration
The import button is placed in the Data Management section of the mobile settings screen, directly above the existing export button.
**File**: `mobile/MobileSettingsScreen.tsx`
- Added ImportButton component
- Added ImportDialog component
- Manages file selection and dialog state
## Usage Flow
1. User clicks "Import My Data" button
2. File selector opens (.tar.gz filter)
3. User selects export archive
4. Dialog opens and automatically generates preview
5. Preview shows counts, conflicts, warnings
6. User selects mode (merge or replace)
7. User confirms import
8. Progress indicator shows during import
9. Results screen displays summary with counts
10. User clicks "Done" to close dialog
## Validation
- Client-side: File extension (.tar.gz), size (500MB max)
- Server-side: MIME type, magic bytes, archive structure, manifest validation
- User-facing error messages for all failure scenarios
## Responsive Design
- Mobile (320px): Full-width dialog, stacked layout, 44px touch targets
- Tablet (768px): Centered dialog, readable text
- Desktop (1920px): Max-width constrained dialog (2xl = 672px)
## Quality Checklist
- [x] Type-check passes
- [x] Linting passes
- [x] Mobile viewport support (320px, 768px)
- [x] Desktop viewport support (1920px)
- [x] Touch targets >= 44px
- [x] Error handling with user-friendly messages
- [x] Loading states for async operations
- [x] Success/error toast notifications
- [x] Follows existing export button pattern
- [x] Material-UI component consistency
- [x] Dark mode support